From f9168ae46409bb4a7908c48f4385cb3ac4bc6888 Mon Sep 17 00:00:00 2001 From: Julian Achatzi Date: Fri, 28 Mar 2025 14:55:31 +0100 Subject: [PATCH] arch: common: Make nocache region loadable The `nocache` is not loadable, thus data stored therein cannot be initialized by the startup code. This might be needed in special cases. E.g. One might have a buffer which one wants to DMA into, and which is a member of a struct. Other members of the struct one may want to have initialized by the startup code. The buffer thus should be placed in the `nocache` region, but for the other members of the buffer to be initialized by the startup code, the `nocache` region needs to be loadable. Fix it by making the `nocache` region loadable. Adding a KConfig symbol to do this optionally was considered, but deemed unnecessary during the PR. Signed-off-by: Julian Achatzi --- arch/common/nocache.ld | 5 +++-- include/zephyr/linker/linker-defs.h | 1 + kernel/xip.c | 6 ++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/common/nocache.ld b/arch/common/nocache.ld index a4e500e8b17..749e88c9aed 100644 --- a/arch/common/nocache.ld +++ b/arch/common/nocache.ld @@ -8,7 +8,7 @@ /* Copied from linker.ld */ /* Non-cached region of RAM */ -SECTION_DATA_PROLOGUE(_NOCACHE_SECTION_NAME,(NOLOAD),) +SECTION_DATA_PROLOGUE(_NOCACHE_SECTION_NAME,,) { #if defined(CONFIG_MMU) MMU_ALIGN; @@ -27,5 +27,6 @@ SECTION_DATA_PROLOGUE(_NOCACHE_SECTION_NAME,(NOLOAD),) MPU_ALIGN(_nocache_ram_size); #endif _nocache_ram_end = .; -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) +} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) _nocache_ram_size = _nocache_ram_end - _nocache_ram_start; +_nocache_load_start = LOADADDR(_NOCACHE_SECTION_NAME); diff --git a/include/zephyr/linker/linker-defs.h b/include/zephyr/linker/linker-defs.h index 0f28985233a..34f6bc3b804 100644 --- a/include/zephyr/linker/linker-defs.h +++ b/include/zephyr/linker/linker-defs.h @@ -225,6 +225,7 @@ extern char __sg_size[]; extern char _nocache_ram_start[]; extern char _nocache_ram_end[]; extern char _nocache_ram_size[]; +extern char _nocache_load_start[]; #endif /* CONFIG_NOCACHE_MEMORY */ /* Memory owned by the kernel. Start and end will be aligned for memory diff --git a/kernel/xip.c b/kernel/xip.c index 550df11d7aa..9973b6ef595 100644 --- a/kernel/xip.c +++ b/kernel/xip.c @@ -31,6 +31,12 @@ void z_data_copy(void) z_early_memcpy(&__ramfunc_region_start, &__ramfunc_load_start, __ramfunc_end - __ramfunc_region_start); #endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */ +#ifdef CONFIG_ARCH_HAS_NOCACHE_MEMORY_SUPPORT +#if CONFIG_NOCACHE_MEMORY + z_early_memcpy(&_nocache_ram_start, &_nocache_load_start, + (uintptr_t) &_nocache_ram_size); +#endif /* CONFIG_NOCACHE_MEMORY */ +#endif /* CONFIG_ARCH_HAS_NOCACHE_MEMORY_SUPPORT */ #if DT_NODE_HAS_STATUS_OKAY(DT_CHOSEN(zephyr_ccm)) z_early_memcpy(&__ccm_data_start, &__ccm_data_load_start, __ccm_data_end - __ccm_data_start);