1/* 2 * Copyright (c) 2020 Synopsys. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7/** 8 * @brief Common parts of the linker scripts for the ARCv2 targets for 9 * GNU and MWDT toolchains. 10 */ 11 12#include <zephyr/linker/sections.h> 13#include <zephyr/linker/linker-defs.h> 14#include <zephyr/linker/linker-tool.h> 15 16/* physical address of RAM */ 17#ifdef CONFIG_HARVARD 18 #define ROMABLE_REGION ICCM 19 #define RAMABLE_REGION DCCM 20 #define ROM_RAM_IN_SAME_REGION 0 21#else 22 #if defined(CONFIG_XIP) && (FLASH_SIZE != 0) 23 #define ROMABLE_REGION FLASH 24 #define RAMABLE_REGION SRAM 25 #define ROM_RAM_IN_SAME_REGION 0 26 #else 27 #define ROMABLE_REGION SRAM 28 #define RAMABLE_REGION SRAM 29 #define ROM_RAM_IN_SAME_REGION 1 30 #endif 31#endif 32 33#ifdef CONFIG_ARC_MPU_ENABLE 34 #if CONFIG_ARC_MPU_VER == 2 35 #define MPU_MIN_SIZE 2048 36 #elif (CONFIG_ARC_MPU_VER == 3) || (CONFIG_ARC_MPU_VER == 4) || \ 37 (CONFIG_ARC_MPU_VER == 6) || (CONFIG_ARC_MPU_VER == 8) 38 #define MPU_MIN_SIZE 32 39 #endif 40 #define MPU_MIN_SIZE_ALIGN . = ALIGN(MPU_MIN_SIZE); 41 #if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT) 42 #define MPU_ALIGN(region_size) \ 43 . = ALIGN(MPU_MIN_SIZE); \ 44 . = ALIGN( 1 << LOG2CEIL(region_size)) 45 #else 46 #define MPU_ALIGN(region_size) \ 47 . = ALIGN(MPU_MIN_SIZE) 48 #endif 49#else 50 #define MPU_MIN_SIZE_ALIGN 51 #define MPU_ALIGN(region_size) . = ALIGN(4) 52#endif 53 54OUTPUT_ARCH(arc) 55ENTRY(CONFIG_KERNEL_ENTRY) 56 57MEMORY { 58#ifdef FLASH_START 59 FLASH (rx) : ORIGIN = FLASH_START, LENGTH = FLASH_SIZE 60#endif 61#ifdef ICCM_START 62 ICCM (rwx) : ORIGIN = ICCM_START, LENGTH = ICCM_SIZE 63#endif 64#ifdef SRAM_START 65 SRAM (rwx) : ORIGIN = SRAM_START, LENGTH = SRAM_SIZE 66#endif 67#ifdef DCCM_START 68 DCCM (rw) : ORIGIN = DCCM_START, LENGTH = DCCM_SIZE 69#endif 70#ifdef XCCM_START 71 XCCM (rw) : ORIGIN = XCCM_START, LENGTH = XCCM_SIZE 72#endif 73#ifdef YCCM_START 74 YCCM (rw) : ORIGIN = YCCM_START, LENGTH = YCCM_SIZE 75#endif 76 /* Used by and documented in include/linker/intlist.ld */ 77 IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K 78} 79 80SECTIONS { 81 82#include <zephyr/linker/rel-sections.ld> 83 84 GROUP_START(ROMABLE_REGION) 85 86 SECTION_PROLOGUE(_TEXT_SECTION_NAME,,ALIGN(1024)) { 87 __rom_region_start = .; 88 __text_region_start = .; 89 90/* Located in generated directory. This file is populated by the 91 * zephyr_linker_sources() Cmake function. 92 */ 93#include <snippets-rom-start.ld> 94 *(.text .text.*) 95 *(.gnu.linkonce.t.*) 96 97 . = ALIGN(4); 98#include <zephyr/linker/kobject-text.ld> 99 } GROUP_LINK_IN(ROMABLE_REGION) 100 101 __text_region_end = .; 102 __rodata_region_start = .; 103 104#include <zephyr/linker/common-rom.ld> 105#ifdef __MWDT_LINKER_CMD__ 106 SECTION_DATA_PROLOGUE(tdata,,) 107 { 108 *(.tls .tls.*); 109 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 110 111 #ifdef CONFIG_XIP 112 /* The "primary copy" of tls should be only in flash on XIP systems */ 113 PROVIDE(_arcmwdt_tls_start = LOADADDR(tdata)); 114 #else 115 PROVIDE(_arcmwdt_tls_start = ADDR(tdata)); 116 #endif 117 118 PROVIDE(_arcmwdt_tls_size = SIZEOF(tdata)); 119 120/* TODO: add mwdt specific ROM C++ sections */ 121#else 122#include <zephyr/linker/thread-local-storage.ld> 123#include <zephyr/linker/cplusplus-rom.ld> 124#endif /* __MWDT_LINKER_CMD__ */ 125 126 SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) { 127 *(".rodata") 128 *(".rodata.*") 129 *(.gnu.linkonce.r.*) 130 131/* Located in generated directory. This file is populated by the 132 * zephyr_linker_sources() Cmake function. 133 */ 134#include <snippets-rodata.ld> 135#include <zephyr/linker/kobject-rom.ld> 136 137#if defined(CONFIG_CPP) && !defined(CONFIG_CPP_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__) 138 . = ALIGN(4); 139 _fctors = .; 140 KEEP(*(.ctors*)) 141 _ectors = .; 142#endif /* CONFIG_CPP && !CONFIG_CPP_STATIC_INIT_GNU && __MWDT_LINKER_CMD__ */ 143 144/* This extra MPU alignment of RAMABLE_REGION is only required if we put ROMABLE_REGION and 145 * RAMABLE_REGION into the same (continuous) memory - otherwise we can get beginning of the 146 * RAMABLE_REGION in the end of ROMABLE_REGION MPU aperture. 147 */ 148#if ROM_RAM_IN_SAME_REGION 149 MPU_ALIGN(ABSOLUTE(.) - __rom_region_start); 150#endif 151 } GROUP_LINK_IN(ROMABLE_REGION) 152 153 __rodata_region_end = .; 154 155 MPU_ALIGN(__rodata_region_end - __rom_region_start); 156 __rom_region_end = .; 157 __rom_region_size = __rom_region_end - __rom_region_start; 158 159 GROUP_END(ROMABLE_REGION) 160 161 GROUP_START(RAMABLE_REGION) 162 163 MPU_MIN_SIZE_ALIGN 164 165 _image_ram_start = .; 166 167#include <app_data_alignment.ld> 168 169/* Located in generated directory. This file is populated by the 170 * zephyr_linker_sources() Cmake function. 171 */ 172#include <snippets-ram-sections.ld> 173 174#if defined(CONFIG_USERSPACE) 175#define APP_SHARED_ALIGN MPU_MIN_SIZE_ALIGN 176#define SMEM_PARTITION_ALIGN MPU_ALIGN 177 178#include <app_smem.ld> 179 _app_smem_size = _app_smem_end - _app_smem_start; 180 _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME); 181#endif /* CONFIG_USERSPACE */ 182 183 SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) { 184 MPU_MIN_SIZE_ALIGN 185 /* 186 * For performance, BSS section is assumed to be 4 byte aligned and 187 * a multiple of 4 bytes 188 */ 189 . = ALIGN(4); 190 __bss_start = .; 191 __kernel_ram_start = .; 192 *(".bss") 193 *(".bss.*") 194 *(COMMON) 195 *(".kernel_bss.*") 196 197 /* 198 * BSP clears this memory in words only and doesn't clear any 199 * potential left over bytes. 200 */ 201 __bss_end = ALIGN(4); 202 } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) 203 204#include <zephyr/linker/common-noinit.ld> 205 206 GROUP_START(DATA_REGION) 207 208 SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,) { 209 210/* when XIP, .text is in ROM, but vector table must be at start of .data */ 211 __data_region_start = .; 212 __data_start = .; 213 *(".data") 214 *(".data.*") 215 *(".kernel.*") 216 217/* Located in generated directory. This file is populated by the 218 * zephyr_linker_sources() Cmake function. 219 */ 220#include <snippets-rwdata.ld> 221 222 __data_end = .; 223 224 } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 225 226 __data_size = __data_end - __data_start; 227 __data_load_start = LOADADDR(_DATA_SECTION_NAME); 228 229 __data_region_load_start = LOADADDR(_DATA_SECTION_NAME); 230 231#include <zephyr/linker/common-ram.ld> 232#include <zephyr/linker/kobject-data.ld> 233 234#ifdef __MWDT_LINKER_CMD__ 235/* TODO: add mwdt specific RAM C++ sections */ 236#else 237#include <zephyr/linker/cplusplus-ram.ld> 238#endif /* __MWDT_LINKER_CMD__ */ 239 240/* Located in generated directory. This file is populated by the 241 * zephyr_linker_sources() Cmake function. 242 */ 243#include <snippets-data-sections.ld> 244 245 __data_region_end = .; 246 247 MPU_MIN_SIZE_ALIGN 248 /* Define linker symbols */ 249 250 __kernel_ram_end = .; 251 __kernel_ram_size = __kernel_ram_end - __kernel_ram_start; 252 253#ifdef __MWDT_LINKER_CMD__ 254/* mwdt requires _fstack, _estack which will be used in _stkchk. 255 * _stkchk is inserted by mwdt automatically, if _fstack, _estack is not 256 * set correctly, the brk_s instruction will be called 257 * here, we use a trick to deceive the compiler. 258 */ 259 _fstack = _image_ram_start; 260 _estack = .; 261#endif /* __MWDT_LINKER_CMD__ */ 262 263#ifdef CONFIG_ARC_XY_ENABLE 264 SECTION_PROLOGUE(xdata,,) 265 { 266 __xdata_start = .; 267 *(.Xdata*) 268 __xdata_end = .; 269 } GROUP_DATA_LINK_IN(XCCM, RAMABLE_REGION) 270 271 SECTION_PROLOGUE(ydata,,) 272 { 273 __ydata_start = .; 274 *(.Ydata*) 275 __ydata_end = .; 276 } GROUP_DATA_LINK_IN(YCCM, RAMABLE_REGION) 277#endif 278 279/* Located in generated directory. This file is populated by the 280 * zephyr_linker_sources() Cmake function. 281 */ 282#include <snippets-sections.ld> 283 284#include <zephyr/linker/ram-end.ld> 285 286 GROUP_END(RAMABLE_REGION) 287 288#include <zephyr/linker/debug-sections.ld> 289 290 SECTION_PROLOGUE(.ARC.attributes, 0,) { 291 KEEP(*(.ARC.attributes)) 292 KEEP(*(.gnu.attributes)) 293 } 294 295#if !defined(CONFIG_XIP) 296 /* 297 * Zephyr uses _estack as a start of heap allocation area. 298 * Region [_estack .. sram_end] should be defined in MPU. 299 * Including _image_ram region which is [_image_ram_start .. _image_ram_end] 300 * we get [_image_ram_start .. sram_end] region to be defined in MPU. 301 */ 302 __arc_rw_sram_size = SRAM_START + SRAM_SIZE - _image_ram_start; 303#endif 304 305 /DISCARD/ : { 306#if defined(CONFIG_CPP) && !defined(CONFIG_CPP_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__) 307 *(.dtors*) 308 *(.fini*) 309 *(.eh_frame*) 310#endif /* CONFIG_CPP && !CONFIG_CPP_STATIC_INIT_GNU && __MWDT_LINKER_CMD__ */ 311 *(.note.GNU-stack) 312 *(.got.plt) 313 *(.igot.plt) 314 *(.got) 315 *(.igot) 316 } 317} 318