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 <swift.tian@ambiq.com>
This commit is contained in:
Swift Tian 2025-04-03 17:54:26 +08:00 committed by Benjamin Cabé
commit 92fa83fc47
6 changed files with 74 additions and 4 deletions

View file

@ -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 "")

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,13 @@
/*
* Copyright (c) 2025 Ambiq Micro Inc. <www.ambiq.com>
*
* 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)

View file

@ -7,7 +7,16 @@
#include <zephyr/init.h>
#include <zephyr/cache.h>
#include <zephyr/logging/log.h>
#include "soc.h"
#include <zephyr/mem_mgmt/mem_attr.h>
#ifdef CONFIG_DCACHE
#include <zephyr/dt-bindings/memory-attr/memory-attr-arm.h>
#endif /* CONFIG_DCACHE */
#ifdef CONFIG_NOCACHE_MEMORY
#include <zephyr/linker/linker-defs.h>
#endif /* CONFIG_NOCACHE_MEMORY */
#include <soc.h>
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

View file

@ -9,4 +9,6 @@
#include <am_mcu_apollo.h>
bool buf_in_nocache(uintptr_t buf, size_t len_bytes);
#endif /* __SOC_H__ */