diff --git a/boards/arc/qemu_arc/arc_mpu_regions.c b/boards/arc/qemu_arc/arc_mpu_regions.c index d9f53e3d19577..227cd831d4647 100644 --- a/boards/arc/qemu_arc/arc_mpu_regions.c +++ b/boards/arc/qemu_arc/arc_mpu_regions.c @@ -6,6 +6,7 @@ #include #include +#include #include /* @@ -23,12 +24,31 @@ static struct arc_mpu_region mpu_regions[] = { #endif /* CONFIG_COVERAGE_GCOV && CONFIG_USERSPACE */ #if DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) > 0 + +#ifdef CONFIG_XIP /* Region RAM */ MPU_REGION_ENTRY("RAM", DT_REG_ADDR(DT_CHOSEN(zephyr_sram)), DT_REG_SIZE(DT_CHOSEN(zephyr_sram)), REGION_KERNEL_RAM_ATTR | REGION_DYNAMIC), -#endif +#else + /* Region RAM */ + /* + * In case if Zephyr is configured with CONFIG_XIP=n it linked into + * SRAM. So RAM region should have EXECUTE permission. + */ + MPU_REGION_ENTRY("RAM_RX", + (uintptr_t)__rom_region_start, + (uintptr_t)__rom_region_size, + REGION_ROM_ATTR), + + MPU_REGION_ENTRY("RAM_RW", + (uintptr_t)_image_ram_start, + (uintptr_t)__arc_rw_sram_size, + REGION_KERNEL_RAM_ATTR | REGION_DYNAMIC), +#endif /* CONFIG_XIP */ + +#endif /* zephyr_sram > 0 */ #if DT_REG_SIZE(DT_CHOSEN(zephyr_flash)) > 0 /* Region DCCM */ diff --git a/include/zephyr/arch/arc/arch.h b/include/zephyr/arch/arc/arch.h index 59730aa5aa7ef..50e211641d3bf 100644 --- a/include/zephyr/arch/arc/arch.h +++ b/include/zephyr/arch/arc/arch.h @@ -344,6 +344,10 @@ static ALWAYS_INLINE void arch_nop(void) __builtin_arc_nop(); } +#ifndef CONFIG_XIP +extern char __arc_rw_sram_size[]; +#endif /* CONFIG_XIP */ + #endif /* _ASMLANGUAGE */ #ifdef __cplusplus diff --git a/include/zephyr/arch/arc/v2/linker.ld b/include/zephyr/arch/arc/v2/linker.ld index bfbc08cc9c4ce..120ba618b03d8 100644 --- a/include/zephyr/arch/arc/v2/linker.ld +++ b/include/zephyr/arch/arc/v2/linker.ld @@ -93,6 +93,11 @@ SECTIONS { #include #include +#ifdef __MWDT_LINKER_CMD__ +/* TODO: add mwdt specific ROM C++ sections */ +#else +#include +#endif /* __MWDT_LINKER_CMD__ */ SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) { *(".rodata") @@ -103,7 +108,6 @@ SECTIONS { * zephyr_linker_sources() Cmake function. */ #include - #include #if defined(CONFIG_CPLUSPLUS) && !defined(CONFIG_CPP_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__) @@ -112,15 +116,12 @@ SECTIONS { KEEP(*(.ctors*)) _ectors = .; #endif /* CONFIG_CPLUSPLUS && !CONFIG_CPP_STATIC_INIT_GNU && __MWDT_LINKER_CMD__ */ - } GROUP_LINK_IN(ROMABLE_REGION) -#ifdef __MWDT_LINKER_CMD__ -/* TODO: add mwdt specific ROM C++ sections */ -#else -#include -#endif /* __MWDT_LINKER_CMD__ */ + MPU_ALIGN(ABSOLUTE(.) - __rom_region_start); + } GROUP_LINK_IN(ROMABLE_REGION) __rodata_region_end = .; + MPU_ALIGN(__rodata_region_end - __rom_region_start); __rom_region_end = .; __rom_region_size = __rom_region_end - __rom_region_start; @@ -129,6 +130,10 @@ SECTIONS { GROUP_START(RAMABLE_REGION) + MPU_MIN_SIZE_ALIGN + + _image_ram_start = .; + #include /* Located in generated directory. This file is populated by the @@ -141,8 +146,6 @@ SECTIONS { #define SMEM_PARTITION_ALIGN MPU_ALIGN #include - - _image_ram_start = _app_smem_start; _app_smem_size = _app_smem_end - _app_smem_start; _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME); #endif /* CONFIG_USERSPACE */ @@ -155,7 +158,6 @@ SECTIONS { */ . = ALIGN(4); __bss_start = .; - _image_ram_start = .; __kernel_ram_start = .; *(".bss") *(".bss.*") @@ -244,6 +246,16 @@ SECTIONS { KEEP(*(.gnu.attributes)) } +#if !defined(CONFIG_XIP) + /* + * Zephyr uses _estack as a start of heap allocation area. + * Region [_estack .. sram_end] should be defined in MPU. + * Including _image_ram region which is [_image_ram_start .. _image_ram_end] + * we get [_image_ram_start .. sram_end] region to be defined in MPU. + */ + __arc_rw_sram_size = SRAM_START + SRAM_SIZE - _image_ram_start; +#endif + /DISCARD/ : { #if defined(CONFIG_CPLUSPLUS) && !defined(CONFIG_CPP_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__) *(.dtors*)