Roman Okhrimenko | dc0ca08 | 2023-06-21 20:49:51 +0300 | [diff] [blame] | 1 | /***************************************************************************//** |
| 2 | * \file xmc7200d_x8384_cm7.ld |
| 3 | * \version 1.0.0 |
| 4 | * |
| 5 | * Linker file for the GNU C compiler. |
| 6 | * |
| 7 | * The main purpose of the linker script is to describe how the sections in the |
| 8 | * input files should be mapped into the output file, and to control the memory |
| 9 | * layout of the output file. |
| 10 | * |
| 11 | * \note The entry point location is fixed and starts at 0x10000000. The valid |
| 12 | * application image should be placed there. |
| 13 | * |
| 14 | * \note The linker files included with the PDL template projects must be generic |
| 15 | * and handle all common use cases. Your project may not use every section |
| 16 | * defined in the linker files. In that case you may see warnings during the |
| 17 | * build process. In your project, you can simply comment out or remove the |
| 18 | * relevant code in the linker file. |
| 19 | * |
| 20 | ******************************************************************************** |
| 21 | * \copyright |
| 22 | * Copyright 2021 Cypress Semiconductor Corporation |
| 23 | * SPDX-License-Identifier: Apache-2.0 |
| 24 | * |
| 25 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 26 | * you may not use this file except in compliance with the License. |
| 27 | * You may obtain a copy of the License at |
| 28 | * |
| 29 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 30 | * |
| 31 | * Unless required by applicable law or agreed to in writing, software |
| 32 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 33 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 34 | * See the License for the specific language governing permissions and |
| 35 | * limitations under the License. |
| 36 | *******************************************************************************/ |
| 37 | |
| 38 | OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") |
| 39 | GROUP(-lgcc -lc -lnosys ) |
| 40 | SEARCH_DIR(.) |
| 41 | GROUP(libgcc.a libc.a libm.a libnosys.a) |
| 42 | ENTRY(Reset_Handler) |
| 43 | |
| 44 | /* The size of the stack section at the end of CM7 SRAM */ |
| 45 | STACK_SIZE = 0x1000; |
| 46 | RAMVECTORS_ALIGNMENT = 128; |
| 47 | |
| 48 | sram_start_reserve = 0; |
| 49 | |
| 50 | sram_total_size = 0x00100000; /* SRAM0 + SRAM1 */ |
| 51 | sram_private_for_srom = 0x00000800; /* Private SRAM for SROM (e.g. API processing) */ |
| 52 | sram_used_by_boot = 0x0; /* Used during boot by Cypress firmware (content will be overwritten on reset, so it should not be used for loadable sections in case of RAM build configurations) */ |
| 53 | |
| 54 | cm0plus_sram_reserve = 0x00020000; /* cm0 sram size */ |
| 55 | cm7_0_sram_reserve = 0x00030000; /* cm7_0 sram size */ |
| 56 | |
| 57 | code_flash_total_size = 0x00830000; |
| 58 | cm0plus_code_flash_reserve = 0x00080000; |
| 59 | cm7_0_code_flash_reserve = 0x00200000; |
| 60 | |
| 61 | code_flash_base_address = 0x10000000; |
| 62 | sram_base_address = 0x28000000; |
| 63 | |
| 64 | /* SRAM reservations */ |
| 65 | _base_SRAM_CM7_0 = sram_base_address + cm0plus_sram_reserve; |
| 66 | _size_SRAM_CM7_0 = cm7_0_sram_reserve; |
| 67 | /* In case of single CM7 device CM7_1 values should not be used */ |
| 68 | _base_SRAM_CM7_1 = sram_base_address + cm0plus_sram_reserve + cm7_0_sram_reserve; |
| 69 | _size_SRAM_CM7_1 = sram_total_size - cm0plus_sram_reserve - cm7_0_sram_reserve; |
| 70 | |
| 71 | /* Code flash reservations */ |
| 72 | _base_CODE_FLASH_CM0P = code_flash_base_address; |
| 73 | _size_CODE_FLASH_CM0P = cm0plus_code_flash_reserve; |
| 74 | _base_CODE_FLASH_CM7_0 = code_flash_base_address + cm0plus_code_flash_reserve; |
| 75 | _size_CODE_FLASH_CM7_0 = cm7_0_code_flash_reserve; |
| 76 | _base_CODE_FLASH_CM7_1 = code_flash_base_address + cm0plus_code_flash_reserve + cm7_0_code_flash_reserve; |
| 77 | _size_CODE_FLASH_CM7_1 = code_flash_total_size - cm0plus_code_flash_reserve - cm7_0_code_flash_reserve; |
| 78 | |
| 79 | /* Fixed Addresses */ |
| 80 | _base_WORK_FLASH = 0x14000000; |
| 81 | _size_WORK_FLASH = 0x00040000; /* 256K Work flash */ |
| 82 | _base_CM7_0_ITCM = 0xA0000000; |
| 83 | _size_CM7_0_ITCM = 0x00004000; |
| 84 | _base_CM7_0_DTCM = 0xA0010000; |
| 85 | _size_CM7_0_DTCM = 0x00004000; |
| 86 | _base_CM7_1_ITCM = 0xA0100000; |
| 87 | _size_CM7_1_ITCM = 0x00004000; |
| 88 | _base_CM7_1_DTCM = 0xA0110000; |
| 89 | _size_CM7_1_DTCM = 0x00004000; |
| 90 | |
| 91 | /* For the non-dual cm7 device, _CORE_CM7_0_ should be defined and _CORE_CM7_1_ should not be defined */ |
| 92 | _base_SRAM = DEFINED(_CORE_CM7_1_) ? _base_SRAM_CM7_1 : DEFINED(_CORE_CM7_0_) ? _base_SRAM_CM7_0 : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); |
| 93 | _size_SRAM = DEFINED(_CORE_CM7_1_) ? _size_SRAM_CM7_1 : DEFINED(_CORE_CM7_0_) ? _size_SRAM_CM7_0 : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); |
| 94 | _base_CODE_FLASH = DEFINED(_CORE_CM7_1_) ? _base_CODE_FLASH_CM7_1 : DEFINED(_CORE_CM7_0_) ? _base_CODE_FLASH_CM7_0 : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); |
| 95 | _size_CODE_FLASH = DEFINED(_CORE_CM7_1_) ? _size_CODE_FLASH_CM7_1 : DEFINED(_CORE_CM7_0_) ? _size_CODE_FLASH_CM7_0 : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); |
| 96 | _base_SFLASH_USER_DATA = 0x17000800; |
| 97 | _size_SFLASH_USER_DATA = 0x00000800; |
| 98 | _base_SFLASH_NAR = 0x17001A00; |
| 99 | _size_SFLASH_NAR = 0x00000200; |
| 100 | _base_SFLASH_PUB_KEY = 0x17006400; |
| 101 | _size_SFLASH_PUB_KEY = 0x00000C00; |
| 102 | _base_SFLASH_APP_PROT = 0x17007600; |
| 103 | _size_SFLASH_APP_PROT = 0x00000200; |
| 104 | _base_SFLASH_TOC2 = 0x17007C00; |
| 105 | _size_SFLASH_TOC2 = 0x00000200; |
| 106 | _base_XIP = 0x60000000; |
| 107 | _size_XIP = 0x08000000; |
| 108 | _base_EFUSE = 0x90700000; |
| 109 | _size_EFUSE = 0x00100000; |
| 110 | _base_ITCM = DEFINED(_CORE_CM7_1_) ? _base_CM7_1_ITCM : DEFINED(_CORE_CM7_0_) ? _base_CM7_0_ITCM : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); |
| 111 | _size_ITCM = DEFINED(_CORE_CM7_1_) ? _size_CM7_1_ITCM : DEFINED(_CORE_CM7_0_) ? _size_CM7_0_ITCM : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); |
| 112 | _base_DTCM = DEFINED(_CORE_CM7_1_) ? _base_CM7_1_DTCM : DEFINED(_CORE_CM7_0_) ? _base_CM7_0_DTCM : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); |
| 113 | _size_DTCM = DEFINED(_CORE_CM7_1_) ? _size_CM7_1_DTCM : DEFINED(_CORE_CM7_0_) ? _size_CM7_0_DTCM : ASSERT(1<1, "Error: Either_CORE_CM7_0_ or _CORE_CM7_1_ not defined"); |
| 114 | |
| 115 | |
| 116 | /* Force symbol to be entered in the output file as an undefined symbol. Doing |
| 117 | * this may, for example, trigger linking of additional modules from standard |
| 118 | * libraries. You may list several symbols for each EXTERN, and you may use |
| 119 | * EXTERN multiple times. This command has the same effect as the -u command-line |
| 120 | * option. |
| 121 | */ |
| 122 | EXTERN(Reset_Handler) |
| 123 | |
| 124 | /* The MEMORY section below describes the location and size of blocks of memory in the target. |
| 125 | * Use this section to specify the memory regions available for allocation. |
| 126 | */ |
| 127 | MEMORY |
| 128 | { |
| 129 | /* The ram and flash regions control RAM and flash memory allocation for the CM7_0/CM7_1 core. */ |
| 130 | ram (rxw) : ORIGIN = _base_SRAM_CM7_0, LENGTH = _size_SRAM_CM7_0 - 0x10000 /* SRAM */ |
| 131 | flash_cm0p (rx) : ORIGIN = _base_CODE_FLASH_CM0P, LENGTH = _size_CODE_FLASH_CM0P /* CODE flash CM0+ */ |
| 132 | flash (rx) : ORIGIN = _base_CODE_FLASH_CM7_0, LENGTH = 0x20000 /* CODE flash CM7_0/1 */ |
| 133 | |
| 134 | /* This is a 256K flash region used for EEPROM emulation. This region can also be used as the general purpose flash. |
| 135 | * You can assign sections to this memory region for only one of the cores. |
| 136 | */ |
| 137 | em_eeprom (rw) : ORIGIN = _base_WORK_FLASH, LENGTH = _size_WORK_FLASH /* WORK flash */ |
| 138 | |
| 139 | /* The following regions define device specific memory regions and must not be changed. */ |
| 140 | sflash_user_data (rx) : ORIGIN = _base_SFLASH_USER_DATA, LENGTH = _size_SFLASH_USER_DATA /* Supervisory flash: User data */ |
| 141 | sflash_nar (rx) : ORIGIN = _base_SFLASH_NAR, LENGTH = _size_SFLASH_NAR /* Supervisory flash: Normal Access Restrictions (NAR) */ |
| 142 | sflash_public_key (rx) : ORIGIN = _base_SFLASH_PUB_KEY, LENGTH = _size_SFLASH_PUB_KEY /* Supervisory flash: Public Key */ |
| 143 | sflash_app_prot (rx) : ORIGIN = _base_SFLASH_APP_PROT, LENGTH = _size_SFLASH_APP_PROT |
| 144 | sflash_toc_2 (rx) : ORIGIN = _base_SFLASH_TOC2, LENGTH = _size_SFLASH_TOC2 /* Supervisory flash: Table of Content # 2 */ |
| 145 | xip (rx) : ORIGIN = _base_XIP, LENGTH = _size_XIP /* XIP: 128 MB */ |
| 146 | efuse (rx) : ORIGIN = _base_EFUSE, LENGTH = _size_EFUSE /* 1MB */ |
| 147 | itcm (rx) : ORIGIN = _base_ITCM, LENGTH = _size_ITCM /* ITCM */ |
| 148 | dtcm (rx) : ORIGIN = _base_DTCM, LENGTH = _base_DTCM /* DTCM */ |
| 149 | } |
| 150 | |
| 151 | /* Library configurations */ |
| 152 | GROUP(libgcc.a libc.a libm.a libnosys.a) |
| 153 | |
| 154 | SECTIONS |
| 155 | { |
| 156 | /* Cortex-M0+ application flash image area. Comment this section if you don't want to include CM0+ image */ |
| 157 | .cy_cm0p_image ORIGIN(flash_cm0p): |
| 158 | { |
| 159 | . = ALIGN(4); |
| 160 | __cy_m0p_code_start = . ; |
| 161 | KEEP(*(.cy_m0p_image)) |
| 162 | __cy_m0p_code_end = . ; |
| 163 | } > flash_cm0p |
| 164 | |
| 165 | /* Check if .cy_m0p_image size exceeds cm0plus_code_flash_reserve */ |
| 166 | ASSERT(__cy_m0p_code_end < ORIGIN(flash), "CM0+ flash image overflows with CM7, increase CM7 base address ") |
| 167 | |
| 168 | /* Cortex-M7 application flash area */ |
| 169 | .text ORIGIN(flash) : |
| 170 | { |
| 171 | /* Cortex-M7 flash vector table */ |
| 172 | . = ALIGN(4); |
| 173 | __Vectors = . ; |
| 174 | KEEP(*(.vectors)) |
| 175 | . = ALIGN(4); |
| 176 | __Vectors_End = .; |
| 177 | __Vectors_Size = __Vectors_End - __Vectors; |
| 178 | __end__ = .; |
| 179 | |
| 180 | . = ALIGN(4); |
| 181 | *(.text*) |
| 182 | |
| 183 | KEEP(*(.init)) |
| 184 | KEEP(*(.fini)) |
| 185 | |
| 186 | /* .ctors */ |
| 187 | *crtbegin.o(.ctors) |
| 188 | *crtbegin?.o(.ctors) |
| 189 | *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) |
| 190 | *(SORT(.ctors.*)) |
| 191 | *(.ctors) |
| 192 | |
| 193 | /* .dtors */ |
| 194 | *crtbegin.o(.dtors) |
| 195 | *crtbegin?.o(.dtors) |
| 196 | *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) |
| 197 | *(SORT(.dtors.*)) |
| 198 | *(.dtors) |
| 199 | |
| 200 | /* Read-only code (constants). */ |
| 201 | *(.rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) |
| 202 | |
| 203 | KEEP(*(.eh_frame*)) |
| 204 | } > flash |
| 205 | |
| 206 | |
| 207 | .ARM.extab : |
| 208 | { |
| 209 | *(.ARM.extab* .gnu.linkonce.armextab.*) |
| 210 | } > flash |
| 211 | |
| 212 | __exidx_start = .; |
| 213 | |
| 214 | .ARM.exidx : |
| 215 | { |
| 216 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) |
| 217 | } > flash |
| 218 | __exidx_end = .; |
| 219 | |
| 220 | .copy.table : |
| 221 | { |
| 222 | . = ALIGN(4); |
| 223 | __copy_table_start__ = .; |
| 224 | |
| 225 | /* Copy data section to RAM */ |
| 226 | LONG (__etext) /* From */ |
| 227 | LONG (__data_start__) /* To */ |
| 228 | LONG ((__data_end__ - __data_start__)/4) /* Size */ |
| 229 | |
| 230 | __copy_table_end__ = .; |
| 231 | } > flash |
| 232 | |
| 233 | |
| 234 | .zero.table : |
| 235 | { |
| 236 | . = ALIGN(4); |
| 237 | __zero_table_start__ = .; |
| 238 | LONG (__bss_start__) |
| 239 | LONG ((__bss_end__ - __bss_start__)/4) |
| 240 | __zero_table_end__ = .; |
| 241 | } > flash |
| 242 | |
| 243 | __etext = . ; |
| 244 | |
| 245 | |
| 246 | .ramVectors (NOLOAD) : |
| 247 | { |
| 248 | . = ALIGN(RAMVECTORS_ALIGNMENT); |
| 249 | __ram_vectors_start__ = .; |
| 250 | KEEP(*(.ram_vectors)) |
| 251 | __ram_vectors_end__ = .; |
| 252 | } > ram |
| 253 | |
| 254 | |
| 255 | .data __ram_vectors_end__ : |
| 256 | { |
| 257 | . = ALIGN(4); |
| 258 | __data_start__ = .; |
| 259 | |
| 260 | *(vtable) |
| 261 | *(.data*) |
| 262 | |
| 263 | . = ALIGN(4); |
| 264 | /* preinit data */ |
| 265 | PROVIDE_HIDDEN (__preinit_array_start = .); |
| 266 | KEEP(*(.preinit_array)) |
| 267 | PROVIDE_HIDDEN (__preinit_array_end = .); |
| 268 | |
| 269 | . = ALIGN(4); |
| 270 | /* init data */ |
| 271 | PROVIDE_HIDDEN (__init_array_start = .); |
| 272 | KEEP(*(SORT(.init_array.*))) |
| 273 | KEEP(*(.init_array)) |
| 274 | PROVIDE_HIDDEN (__init_array_end = .); |
| 275 | |
| 276 | . = ALIGN(4); |
| 277 | /* finit data */ |
| 278 | PROVIDE_HIDDEN (__fini_array_start = .); |
| 279 | KEEP(*(SORT(.fini_array.*))) |
| 280 | KEEP(*(.fini_array)) |
| 281 | PROVIDE_HIDDEN (__fini_array_end = .); |
| 282 | |
| 283 | KEEP(*(.jcr*)) |
| 284 | . = ALIGN(4); |
| 285 | |
| 286 | KEEP(*(.cy_ramfunc*)) |
| 287 | . = ALIGN(32); |
| 288 | |
| 289 | KEEP(*(cy_sharedmem*)) |
| 290 | . = ALIGN(4); |
| 291 | |
| 292 | __data_end__ = .; |
| 293 | |
| 294 | } > ram AT>flash |
| 295 | |
| 296 | |
| 297 | /* Place variables in the section that should not be initialized during the |
| 298 | * device startup. |
| 299 | */ |
| 300 | .noinit (NOLOAD) : ALIGN(8) |
| 301 | { |
| 302 | KEEP(*(.noinit)) |
| 303 | } > ram |
| 304 | |
| 305 | |
| 306 | /* The uninitialized global or static variables are placed in this section. |
| 307 | * |
| 308 | * The NOLOAD attribute tells linker that .bss section does not consume |
| 309 | * any space in the image. The NOLOAD attribute changes the .bss type to |
| 310 | * NOBITS, and that makes linker to A) not allocate section in memory, and |
| 311 | * A) put information to clear the section with all zeros during application |
| 312 | * loading. |
| 313 | * |
| 314 | * Without the NOLOAD attribute, the .bss section might get PROGBITS type. |
| 315 | * This makes linker to A) allocate zeroed section in memory, and B) copy |
| 316 | * this section to RAM during application loading. |
| 317 | */ |
| 318 | .bss (NOLOAD): |
| 319 | { |
| 320 | . = ALIGN(4); |
| 321 | __bss_start__ = .; |
| 322 | *(.bss*) |
| 323 | *(COMMON) |
| 324 | . = ALIGN(4); |
| 325 | __bss_end__ = .; |
| 326 | } > ram |
| 327 | |
| 328 | |
| 329 | .heap (NOLOAD): |
| 330 | { |
| 331 | __HeapBase = .; |
| 332 | __end__ = .; |
| 333 | end = __end__; |
| 334 | KEEP(*(.heap*)) |
| 335 | . = ORIGIN(ram) + LENGTH(ram) - STACK_SIZE; |
| 336 | __HeapLimit = .; |
| 337 | } > ram |
| 338 | |
| 339 | |
| 340 | /* .stack_dummy section doesn't contains any symbols. It is only |
| 341 | * used for linker to calculate size of stack sections, and assign |
| 342 | * values to stack symbols later */ |
| 343 | .stack_dummy (NOLOAD): |
| 344 | { |
| 345 | KEEP(*(.stack*)) |
| 346 | } > ram |
| 347 | |
| 348 | |
| 349 | /* Set stack top to end of RAM, and stack limit move down by |
| 350 | * size of stack_dummy section */ |
| 351 | __StackTop = ORIGIN(ram) + LENGTH(ram); |
| 352 | __StackLimit = __StackTop - SIZEOF(.stack_dummy); |
| 353 | PROVIDE(__stack = __StackTop); |
| 354 | |
| 355 | /* Check if data + heap + stack exceeds RAM limit */ |
| 356 | ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") |
| 357 | |
| 358 | |
| 359 | /* Emulated EEPROM Flash area */ |
| 360 | .cy_em_eeprom : |
| 361 | { |
| 362 | KEEP(*(.cy_em_eeprom)) |
| 363 | } > em_eeprom |
| 364 | |
| 365 | |
| 366 | /* Supervisory Flash: User data */ |
| 367 | .cy_sflash_user_data : |
| 368 | { |
| 369 | KEEP(*(.cy_sflash_user_data)) |
| 370 | } > sflash_user_data |
| 371 | |
| 372 | |
| 373 | /* Supervisory Flash: Normal Access Restrictions (NAR) */ |
| 374 | .cy_sflash_nar : |
| 375 | { |
| 376 | KEEP(*(.cy_sflash_nar)) |
| 377 | } > sflash_nar |
| 378 | |
| 379 | |
| 380 | /* Supervisory Flash: Public Key */ |
| 381 | .cy_sflash_public_key : |
| 382 | { |
| 383 | KEEP(*(.cy_sflash_public_key)) |
| 384 | } > sflash_public_key |
| 385 | |
| 386 | |
| 387 | /* Supervisory Flash: Table of Content # 2 */ |
| 388 | .cy_toc_part2 : |
| 389 | { |
| 390 | KEEP(*(.cy_toc_part2)) |
| 391 | } > sflash_toc_2 |
| 392 | |
| 393 | /* Places the code in the Execute in Place (XIP) section. See the smif driver |
| 394 | * documentation for details. |
| 395 | */ |
| 396 | cy_xip : |
| 397 | { |
| 398 | __cy_xip_start = .; |
| 399 | KEEP(*(.cy_xip)) |
| 400 | __cy_xip_end = .; |
| 401 | } > xip |
| 402 | |
| 403 | |
| 404 | /* eFuse */ |
| 405 | .cy_efuse : |
| 406 | { |
| 407 | KEEP(*(.cy_efuse)) |
| 408 | } > efuse |
| 409 | |
| 410 | /* itcm */ |
| 411 | .cy_itcm : |
| 412 | { |
| 413 | KEEP(*(.cy_itcm)) |
| 414 | } > itcm |
| 415 | |
| 416 | /* dtcm */ |
| 417 | .cy_dtcm : |
| 418 | { |
| 419 | KEEP(*(.cy_dtcm)) |
| 420 | } > dtcm |
| 421 | } |
| 422 | |
| 423 | |
| 424 | /*============================================================ |
| 425 | * Symbols for use by application |
| 426 | *============================================================ |
| 427 | */ |
| 428 | |
| 429 | __ecc_init_sram_start_address = ORIGIN(ram); |
| 430 | __ecc_init_sram_end_address = ORIGIN(ram) + LENGTH(ram); |
| 431 | |
| 432 | /* EOF */ |