diff --git a/doc/reference/devicetree/api.rst b/doc/reference/devicetree/api.rst index c84a4d86edd..5fa26797c7a 100644 --- a/doc/reference/devicetree/api.rst +++ b/doc/reference/devicetree/api.rst @@ -351,6 +351,8 @@ the source code to specify a device name. - A node whose ``reg`` is used by the OpenAMP subsystem to determine the base address and size of the shared memory (SHM) usable for interprocess-communication (IPC) + * - zephyr,itcm + - Instruction Tightly Coupled Memory node on some Arm SoCs * - zephyr,shell-uart - Sets default :option:`CONFIG_UART_SHELL_ON_DEV_NAME` * - zephyr,sram diff --git a/include/arch/arm/aarch32/cortex_m/scripts/linker.ld b/include/arch/arm/aarch32/cortex_m/scripts/linker.ld index 9538b3483cc..2b3e796be5d 100644 --- a/include/arch/arm/aarch32/cortex_m/scripts/linker.ld +++ b/include/arch/arm/aarch32/cortex_m/scripts/linker.ld @@ -71,6 +71,11 @@ #define CCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ccm)) #endif +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay) +#define ITCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_itcm)) +#define ITCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_itcm)) +#endif + #if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay) #define DTCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_dtcm)) #define DTCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_dtcm)) @@ -108,6 +113,9 @@ MEMORY #if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_ccm), okay) CCM (rw) : ORIGIN = CCM_ADDR, LENGTH = CCM_SIZE #endif +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay) + ITCM (rw) : ORIGIN = ITCM_ADDR, LENGTH = ITCM_SIZE +#endif #if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay) DTCM (rw) : ORIGIN = DTCM_ADDR, LENGTH = DTCM_SIZE #endif @@ -419,6 +427,23 @@ SECTIONS GROUP_END(RAMABLE_REGION) +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay) +GROUP_START(ITCM) + + SECTION_PROLOGUE(_ITCM_SECTION_NAME,,SUBALIGN(4)) + { + __itcm_start = .; + *(.itcm) + *(".itcm.*") + __itcm_end = .; + } GROUP_LINK_IN(ITCM AT> ROMABLE_REGION) + + __itcm_size = __itcm_end - __itcm_start; + __itcm_rom_start = LOADADDR(_ITCM_SECTION_NAME); + +GROUP_END(ITCM) +#endif + #if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay) GROUP_START(DTCM) diff --git a/include/linker/linker-defs.h b/include/linker/linker-defs.h index 7d4b98c536a..91dc1abb07a 100644 --- a/include/linker/linker-defs.h +++ b/include/linker/linker-defs.h @@ -230,6 +230,13 @@ extern char __ccm_noinit_end[]; extern char __ccm_end[]; #endif +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay) +extern char __itcm_start[]; +extern char __itcm_end[]; +extern char __itcm_size[]; +extern char __itcm_rom_start[]; +#endif + #if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay) extern char __dtcm_data_start[]; extern char __dtcm_data_end[]; diff --git a/include/linker/section_tags.h b/include/linker/section_tags.h index 3ec59849922..71e363916fd 100644 --- a/include/linker/section_tags.h +++ b/include/linker/section_tags.h @@ -23,6 +23,7 @@ #define __ccm_data_section Z_GENERIC_SECTION(_CCM_DATA_SECTION_NAME) #define __ccm_bss_section Z_GENERIC_SECTION(_CCM_BSS_SECTION_NAME) #define __ccm_noinit_section Z_GENERIC_SECTION(_CCM_NOINIT_SECTION_NAME) +#define __itcm_section Z_GENERIC_SECTION(_ITCM_SECTION_NAME) #define __dtcm_data_section Z_GENERIC_SECTION(_DTCM_DATA_SECTION_NAME) #define __dtcm_bss_section Z_GENERIC_SECTION(_DTCM_BSS_SECTION_NAME) #define __dtcm_noinit_section Z_GENERIC_SECTION(_DTCM_NOINIT_SECTION_NAME) diff --git a/include/linker/sections.h b/include/linker/sections.h index 8d30e02ce9a..59e6e345aa4 100644 --- a/include/linker/sections.h +++ b/include/linker/sections.h @@ -43,6 +43,8 @@ #define _CCM_BSS_SECTION_NAME .ccm_bss #define _CCM_NOINIT_SECTION_NAME .ccm_noinit +#define _ITCM_SECTION_NAME .itcm + #define _DTCM_DATA_SECTION_NAME .dtcm_data #define _DTCM_BSS_SECTION_NAME .dtcm_bss #define _DTCM_NOINIT_SECTION_NAME .dtcm_noinit diff --git a/kernel/xip.c b/kernel/xip.c index 1beb7e3f7c4..c59edc456aa 100644 --- a/kernel/xip.c +++ b/kernel/xip.c @@ -35,6 +35,10 @@ void z_data_copy(void) (void)memcpy(&__ccm_data_start, &__ccm_data_rom_start, __ccm_data_end - __ccm_data_start); #endif +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay) + (void)memcpy(&__itcm_start, &__itcm_rom_start, + (uintptr_t) &__itcm_size); +#endif #if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay) (void)memcpy(&__dtcm_data_start, &__dtcm_data_rom_start, __dtcm_data_end - __dtcm_data_start);