From 92fa83fc47be3c71bf3463b0ecf42e2f206fda6e Mon Sep 17 00:00:00 2001 From: Swift Tian Date: Thu, 3 Apr 2025 17:54:26 +0800 Subject: [PATCH] soc: ambiq: add common cache handling for apollo5x soc The buf_in_nocache function is to be used by various device drivers to check if buffer is in noncacheable region. The cacheable DMA buffer shall be put into section .ambiq_dma_buff due to certain restrictions of the SoC. Signed-off-by: Swift Tian --- soc/ambiq/apollo5x/CMakeLists.txt | 2 ++ soc/ambiq/apollo5x/Kconfig | 17 ++++++++++++++ soc/ambiq/apollo5x/Kconfig.defconfig | 11 +++++++--- soc/ambiq/apollo5x/shared_ram.ld | 13 +++++++++++ soc/ambiq/apollo5x/soc.c | 33 +++++++++++++++++++++++++++- soc/ambiq/apollo5x/soc.h | 2 ++ 6 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 soc/ambiq/apollo5x/shared_ram.ld diff --git a/soc/ambiq/apollo5x/CMakeLists.txt b/soc/ambiq/apollo5x/CMakeLists.txt index f4af65d8794..02abb7df2ba 100644 --- a/soc/ambiq/apollo5x/CMakeLists.txt +++ b/soc/ambiq/apollo5x/CMakeLists.txt @@ -8,4 +8,6 @@ zephyr_include_directories(.) zephyr_sources_ifdef(CONFIG_PM power.c) zephyr_include_directories(${ZEPHYR_BASE}/soc/arm/common/cortex_m) +zephyr_linker_sources(SECTIONS shared_ram.ld) + set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/ambiq/apollo5x/Kconfig b/soc/ambiq/apollo5x/Kconfig index 45bd4c8ae14..8d43ba4981b 100644 --- a/soc/ambiq/apollo5x/Kconfig +++ b/soc/ambiq/apollo5x/Kconfig @@ -19,3 +19,20 @@ config SOC_SERIES_APOLLO5X select HAS_PM select SOC_EARLY_INIT_HOOK select REQUIRES_FULL_LIBC + +config SOC_AMBIQ_DCACHE_SIZE + int + default 65536 if SOC_APOLLO510 + +config SOC_AMBIQ_DMA_BUFF_LOCATION + hex "Byte offset to SRAM_BASE_ADDRESS" + default 0x50000 + help + This option specifies the cacheable DMA buffers' start address + +config SOC_AMBIQ_DMA_BUFF_ALIGNMENT + int "Byte alignment of the DMA buffer" + default DCACHE_LINE_SIZE if DCACHE + default 1 + help + This option specifies the DMA buffers' alignment diff --git a/soc/ambiq/apollo5x/Kconfig.defconfig b/soc/ambiq/apollo5x/Kconfig.defconfig index 5803b2ea240..ddcfd2c4414 100644 --- a/soc/ambiq/apollo5x/Kconfig.defconfig +++ b/soc/ambiq/apollo5x/Kconfig.defconfig @@ -9,9 +9,14 @@ rsource "Kconfig.defconfig.apollo5*" config CACHE_MANAGEMENT default y -config AMBIQ_CACHEABLE_DMA_BUFFER_ALIGNMENT - int - default DCACHE_LINE_SIZE +config DCACHE_LINE_SIZE + default 32 + +config DCACHE + default y + +config ICACHE + default y # Need to enlarge the IDLE stack size because the power # management operations are executed in the idle task diff --git a/soc/ambiq/apollo5x/shared_ram.ld b/soc/ambiq/apollo5x/shared_ram.ld new file mode 100644 index 00000000000..3dc13393da6 --- /dev/null +++ b/soc/ambiq/apollo5x/shared_ram.ld @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Ambiq Micro Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_PROLOGUE (ambiq_dma_buff, CONFIG_SRAM_BASE_ADDRESS + CONFIG_SOC_AMBIQ_DMA_BUFF_LOCATION (NOLOAD),) +{ + __ambiq_dma_buff_start = .; + KEEP(*(SORT_BY_NAME(".ambiq_dma_buff*"))) + . = ALIGN(CONFIG_SOC_AMBIQ_DMA_BUFF_ALIGNMENT); + __ambiq_dma_buff_end = .; +} GROUP_LINK_IN(RAMABLE_REGION) diff --git a/soc/ambiq/apollo5x/soc.c b/soc/ambiq/apollo5x/soc.c index 1bad5a03c88..cc0affc7d40 100644 --- a/soc/ambiq/apollo5x/soc.c +++ b/soc/ambiq/apollo5x/soc.c @@ -7,7 +7,16 @@ #include #include #include -#include "soc.h" +#include +#ifdef CONFIG_DCACHE +#include +#endif /* CONFIG_DCACHE */ + +#ifdef CONFIG_NOCACHE_MEMORY +#include +#endif /* CONFIG_NOCACHE_MEMORY */ + +#include LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); @@ -48,3 +57,25 @@ void soc_early_init_hook(void) /* Enable Dcache */ sys_cache_data_enable(); } + +#if CONFIG_CACHE_MANAGEMENT +bool buf_in_nocache(uintptr_t buf, size_t len_bytes) +{ + bool buf_within_nocache = false; + +#if CONFIG_NOCACHE_MEMORY + /* Check if buffer is in nocache region defined by the linker */ + buf_within_nocache = (buf >= ((uintptr_t)_nocache_ram_start)) && + ((buf + len_bytes - 1) <= ((uintptr_t)_nocache_ram_end)); + if (buf_within_nocache) { + return true; + } +#endif /* CONFIG_NOCACHE_MEMORY */ + + /* Check if buffer is in nocache memory region defined in DT */ + buf_within_nocache = mem_attr_check_buf((void *)buf, len_bytes, + DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE)) == 0; + + return buf_within_nocache; +} +#endif diff --git a/soc/ambiq/apollo5x/soc.h b/soc/ambiq/apollo5x/soc.h index a41e87b5df2..4ae90603bc9 100644 --- a/soc/ambiq/apollo5x/soc.h +++ b/soc/ambiq/apollo5x/soc.h @@ -9,4 +9,6 @@ #include +bool buf_in_nocache(uintptr_t buf, size_t len_bytes); + #endif /* __SOC_H__ */