1/* 2 * Copyright (c) 2020 ITE Corporation. All Rights Reserved. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7#include <soc.h> 8#include <zephyr/devicetree.h> 9 10#include <zephyr/linker/sections.h> 11#include <zephyr/linker/devicetree_regions.h> 12 13#include <zephyr/linker/linker-defs.h> 14#include <zephyr/linker/linker-tool.h> 15 16#ifdef CONFIG_XIP 17#define ROMABLE_REGION ROM 18#else 19#define ROMABLE_REGION RAM 20#endif 21#define RAMABLE_REGION RAM 22 23#define _EXCEPTION_SECTION_NAME exceptions 24#define _RESET_SECTION_NAME reset 25 26#ifdef CONFIG_XIP 27#if DT_NODE_HAS_COMPAT_STATUS(DT_CHOSEN(zephyr_flash), soc_nv_flash, okay) 28#ifdef CONFIG_FLASH_LOAD_OFFSET 29#define ROM_BASE (DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) + \ 30 CONFIG_FLASH_LOAD_OFFSET) 31#else /* !CONFIG_FLASH_LOAD_OFFSET */ 32#define ROM_BASE DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) 33#endif /* CONFIG_FLASH_LOAD_OFFSET */ 34#define ROM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_flash)) 35#elif DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_flash), jedec_spi_nor) 36/* For jedec,spi-nor we expect the spi controller to memory map the flash 37 * and for that mapping to be the second register property of the spi 38 * controller. 39 */ 40#define SPI_CTRL DT_PARENT(DT_CHOSEN(zephyr_flash)) 41#define ROM_BASE DT_REG_ADDR_BY_IDX(SPI_CTRL, 1) 42#define ROM_SIZE DT_REG_SIZE_BY_IDX(SPI_CTRL, 1) 43#endif 44#else /* CONFIG_XIP */ 45#define ROM_BASE CONFIG_SRAM_BASE_ADDRESS 46#define ROM_SIZE KB(CONFIG_SRAM_SIZE) 47#endif /* CONFIG_XIP */ 48 49#define RAM_BASE CONFIG_SRAM_BASE_ADDRESS 50#define RAM_SIZE KB(CONFIG_SRAM_SIZE) 51 52#ifdef CONFIG_RISCV_PMP 53 #define MPU_MIN_SIZE 4 54 #define MPU_MIN_SIZE_ALIGN . = ALIGN(MPU_MIN_SIZE); 55 #if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT) 56 #define MPU_ALIGN(region_size) \ 57 . = ALIGN(MPU_MIN_SIZE); \ 58 . = ALIGN( 1 << LOG2CEIL(region_size)) 59 #else 60 #define MPU_ALIGN(region_size) \ 61 . = ALIGN(MPU_MIN_SIZE) 62 #endif 63#else 64 #define MPU_MIN_SIZE_ALIGN 65 #define MPU_ALIGN(region_size) . = ALIGN(4) 66#endif 67 68#include <zephyr/linker/linker-devnull.h> 69 70MEMORY 71{ 72#ifdef CONFIG_XIP 73 ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE 74#endif 75 RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE 76 77#if defined(CONFIG_LINKER_DEVNULL_MEMORY) 78 DEVNULL_ROM (rx) : ORIGIN = DEVNULL_ADDR, LENGTH = DEVNULL_SIZE 79#endif 80 81 LINKER_DT_REGIONS() 82 83 /* Used by and documented in include/linker/intlist.ld */ 84 IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K 85} 86 87ENTRY(CONFIG_KERNEL_ENTRY) 88 89SECTIONS 90 { 91 92#include <zephyr/linker/rel-sections.ld> 93 94#ifdef CONFIG_LLEXT 95#include <zephyr/linker/llext-sections.ld> 96#endif 97 98 /* 99 * The .plt and .iplt are here according to 100 * 'riscv32-zephyr-elf-ld --verbose', before text section. 101 */ 102 SECTION_PROLOGUE(.plt,,) 103 { 104 *(.plt) 105 } 106 107 SECTION_PROLOGUE(.iplt,,) 108 { 109 *(.iplt) 110 } 111 112 GROUP_START(ROMABLE_REGION) 113 __rom_region_start = ROM_BASE; 114 115 SECTION_PROLOGUE(rom_start,,) 116 { 117 . = ALIGN(16); 118/* Located in generated directory. This file is populated by calling 119 * zephyr_linker_sources(ROM_START ...). 120 */ 121#include <snippets-rom-start.ld> 122 } GROUP_LINK_IN(ROMABLE_REGION) 123 124#ifdef CONFIG_CODE_DATA_RELOCATION 125#include <linker_relocate.ld> 126#endif 127 128 SECTION_PROLOGUE(_RESET_SECTION_NAME,,) 129 { 130 KEEP(*(.reset.*)) 131 } GROUP_LINK_IN(ROMABLE_REGION) 132 133#ifdef CONFIG_SOC_IT8XXX2_JTAG_DEBUG_INTERFACE 134#define JTAG_DEBUG_RESERVED_ADDR_START 0x80000800 135#define JTAG_DEBUG_RESERVED_ADDR_END 0x800008FF 136 /* The CPU address from 0x80000800 to 0x800008FF is reserved for JTAG 137 * debug usage. */ 138 SECTION_PROLOGUE(jtag_dbg,,) 139 { 140 __jtag_dbg_pad_start = ABSOLUTE(.); 141 ASSERT((__jtag_dbg_pad_start < JTAG_DEBUG_RESERVED_ADDR_START), 142 "The start address of jtag debug section is incorrect."); 143 144 __jtag_dbg_pad_size = JTAG_DEBUG_RESERVED_ADDR_END - __jtag_dbg_pad_start; 145 . = . + __jtag_dbg_pad_size; 146 147 __jtag_dbg_pad_end = ABSOLUTE(.); 148 ASSERT((__jtag_dbg_pad_end == JTAG_DEBUG_RESERVED_ADDR_END), 149 "The end address of jtag debug section is incorrect."); 150 } GROUP_LINK_IN(ROMABLE_REGION) 151#endif 152 153#ifndef CONFIG_SOC_IT8XXX2_EXCEPTIONS_IN_RAM 154 SECTION_PROLOGUE(_EXCEPTION_SECTION_NAME,,) 155 { 156 KEEP(*(".exception.entry.*")) 157 *(".exception.other.*") 158 } GROUP_LINK_IN(ROMABLE_REGION) 159#endif 160 161 SECTION_PROLOGUE(_TEXT_SECTION_NAME,,) 162 { 163 . = ALIGN(4); 164 KEEP(*(.openocd_debug)) 165 KEEP(*(".openocd_debug.*")) 166 167 __text_region_start = .; 168#ifndef CONFIG_SOC_IT8XXX2_LIBRARY_TO_RAM 169 *(.text) 170 *(".text.*") 171#endif 172 173#ifdef CONFIG_SOC_IT8XXX2_LIBRARY_TO_RAM 174 *(EXCLUDE_FILE ( 175#endif 176#ifdef CONFIG_SOC_IT8XXX2_SERIAL_IN_RAM 177 *libdrivers__serial.a:* 178#endif 179#ifdef CONFIG_SOC_IT8XXX2_KERNEL_IN_RAM 180 *libkernel.a:* 181#endif 182#ifdef CONFIG_SOC_IT8XXX2_ZEPHYR_IN_RAM 183 *libzephyr.a:* 184#endif 185#ifdef CONFIG_SOC_IT8XXX2_LIBRARY_TO_RAM 186 ) 187 .text 188 ) 189#endif 190 191#ifdef CONFIG_SOC_IT8XXX2_LIBRARY_TO_RAM 192 *(EXCLUDE_FILE ( 193#endif 194#ifdef CONFIG_SOC_IT8XXX2_SERIAL_IN_RAM 195 *libdrivers__serial.a:* 196#endif 197#ifdef CONFIG_SOC_IT8XXX2_KERNEL_IN_RAM 198 *libkernel.a:* 199#endif 200#ifdef CONFIG_SOC_IT8XXX2_ZEPHYR_IN_RAM 201 *libzephyr.a:* 202#endif 203#ifdef CONFIG_SOC_IT8XXX2_LIBRARY_TO_RAM 204 ) 205 .text.* 206 ) 207#endif 208 *(.gnu.linkonce.t.*) 209#include <zephyr/linker/kobject-text.ld> 210 211 /* IT8xxx2 requires memory mappings be configured for execution 212 * out of RAM, which refer to contiguous blocks of RAM. Place 213 * all relevant sections together to minimize RAM waste. */ 214 . = ALIGN(0x1000); 215 /* Mapping base address must be 4k-aligned */ 216 __ilm_flash_start = .; 217#ifdef CONFIG_SOC_IT8XXX2_SHA256_HW_ACCELERATE 218 /* Pad to match allocation of block in RAM, 219 * maintaining code alignment against ILM */ 220 __sha256_pad_block_start = .; 221 . = . + CONFIG_SOC_IT8XXX2_SHA256_BLOCK_SIZE; 222#endif 223 /* Specially-tagged functions in SoC sources */ 224 KEEP(*(.__ram_code)) 225 *(.__ram_code.*) 226#ifdef CONFIG_SOC_IT8XXX2_EXCEPTIONS_IN_RAM 227 KEEP(*(".exception.entry.*")) 228 *(".exception.other.*") 229#endif 230#ifdef CONFIG_SOC_IT8XXX2_SERIAL_IN_RAM 231 *libdrivers__serial.a:*(.text .text.*) 232 *libdrivers__serial.a:*(.rodata .rodata.*) 233 *libdrivers__serial.a:*(.srodata .srodata.*) 234#endif 235#ifdef CONFIG_SOC_IT8XXX2_KERNEL_IN_RAM 236 *libkernel.a:*(.text .text.*) 237 *libkernel.a:*(.rodata .rodata.*) 238 *libkernel.a:*(.srodata .srodata.*) 239#endif 240#ifdef CONFIG_SOC_IT8XXX2_ZEPHYR_IN_RAM 241 *libzephyr.a:*(.text .text.*) 242 *libzephyr.a:*(.rodata .rodata.*) 243 *libzephyr.a:*(.srodata .srodata.*) 244#endif 245 __ilm_flash_end = .; 246 /* ILM mapping is always a multiple of 4k size; ensure following 247 * sections won't incorrectly redirect to RAM. */ 248 . = ALIGN(0x1000); 249 250 } GROUP_LINK_IN(ROMABLE_REGION) 251 252 __text_region_end = .; 253 254 __rodata_region_start = .; 255#include <zephyr/linker/common-rom.ld> 256/* Located in generated directory. This file is populated by calling 257 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs. 258 */ 259#include <snippets-rom-sections.ld> 260#include <zephyr/linker/thread-local-storage.ld> 261 262 SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) 263 { 264 . = ALIGN(4); 265 *(.srodata) 266 *(".srodata.*") 267 *(.rodata) 268 *(".rodata.*") 269 *(.gnu.linkonce.r.*) 270 *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) 271 272/* Located in generated directory. This file is populated by the 273 * zephyr_linker_sources() Cmake function. 274 */ 275#include <snippets-rodata.ld> 276#include <zephyr/linker/kobject-rom.ld> 277 . = ALIGN(4); 278 } GROUP_LINK_IN(ROMABLE_REGION) 279 280#include <zephyr/linker/cplusplus-rom.ld> 281 __rodata_region_end = .; 282 283 /* For non-XIP system, __rom_region_end symbol should be set to 284 * the end of common ROMABLE_REGIONs (text and rodata) instead of 285 * the linker script end, so it wouldn't mistakenly contain 286 * RAMABLE_REGION in it. 287 */ 288#ifndef CONFIG_XIP 289#ifdef CONFIG_RISCV_PMP 290 SECTION_PROLOGUE(rom_mpu_padding,,) 291 { 292 MPU_ALIGN(__rodata_region_end - __rom_region_start); 293#ifdef CONFIG_QEMU_TARGET 294 /* 295 * QEMU doesn't vet each instruction fetch individually. 296 * Instead, it grabs a whole page and perform dynamic 297 * transation on it in a batch. It therefore validates 298 * PMP permissions using page-sized and -aligned chunks. 299 */ 300 . = ALIGN(0x1000); 301#endif 302 } GROUP_LINK_IN(ROMABLE_REGION) 303#endif /* CONFIG_RISCV_PMP */ 304 305 __rom_region_end = .; 306 __rom_region_size = __rom_region_end - __rom_region_start; 307#endif /* CONFIG_XIP */ 308 GROUP_END(ROMABLE_REGION) 309 310 GROUP_START(RAMABLE_REGION) 311 312 . = RAM_BASE; 313 314 /* Claim RAM for ILM mappings; must be 4k-aligned and each mapping is 4k in 315 * size, but mapped regions can still be accessed as data so don't need to be 316 * padded out to 4k size. This doesn't load any sections because code in ILM 317 * is still accessed at its VMA in ROM. */ 318 SECTION_PROLOGUE(ilm_ram,(NOLOAD),ALIGN(0x1000)) 319 { 320 __ilm_ram_start = .; 321 322#ifdef CONFIG_SOC_IT8XXX2_SHA256_HW_ACCELERATE 323 __sha256_ram_block_start = .; 324 KEEP(*(.__sha256_ram_block)) 325 __sha256_ram_block_size = \ 326 ABSOLUTE(. - __sha256_ram_block_start); 327 __sha256_ram_block_end = .; 328 329 ASSERT((__sha256_ram_block_size == CONFIG_SOC_IT8XXX2_SHA256_BLOCK_SIZE), \ 330 "Not compatible ram size for HW sha256 module"); 331 ASSERT((__sha256_ram_block_end < (RAM_BASE + 0x1000)), \ 332 "sha256 ram block must in SRAM first 4kbytes"); 333 ASSERT(((ABSOLUTE(__sha256_ram_block_start) & 0xfff) == \ 334 (ABSOLUTE(__sha256_pad_block_start) & 0xfff)), \ 335 "sha256 ram block needs the same offset with sha256 rom block"); 336#else 337 __sha256_ram_block_size = 0; 338#endif 339 . += __ilm_flash_end - __ilm_flash_start - __sha256_ram_block_size; 340 __ilm_ram_end = .; 341 } GROUP_LINK_IN(RAMABLE_REGION) 342 343 _image_ram_start = .; 344/* Located in generated directory. This file is populated by the 345 * zephyr_linker_sources() Cmake function. 346 */ 347#include <snippets-ram-sections.ld> 348 349#if defined(CONFIG_USERSPACE) 350#define APP_SHARED_ALIGN MPU_MIN_SIZE_ALIGN 351#define SMEM_PARTITION_ALIGN MPU_ALIGN 352 353#include <app_smem.ld> 354 355 _app_smem_size = _app_smem_end - _app_smem_start; 356 _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME); 357#endif /* CONFIG_USERSPACE */ 358 359 SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) 360 { 361 MPU_MIN_SIZE_ALIGN 362 /* 363 * For performance, BSS section is assumed to be 4 byte aligned and 364 * a multiple of 4 bytes 365 */ 366 . = ALIGN(4); 367 __bss_start = .; 368 __kernel_ram_start = .; 369 *(.sbss) 370 *(".sbss.*") 371 *(.bss) 372 *(".bss.*") 373 COMMON_SYMBOLS 374 375#ifdef CONFIG_CODE_DATA_RELOCATION 376#include <linker_sram_bss_relocate.ld> 377#endif 378 379 /* 380 * As memory is cleared in words only, it is simpler to ensure the BSS 381 * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes. 382 */ 383 __bss_end = ALIGN(4); 384 } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) 385 386#include <zephyr/linker/common-noinit.ld> 387 388 SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,) 389 { 390 . = ALIGN(4); 391 /* _image_ram_start = .; */ 392 __data_region_start = .; 393 __data_start = .; 394 395 *(.data) 396 *(".data.*") 397 398#ifdef CONFIG_RISCV_GP 399 /* 400 * RISC-V architecture has 12-bit signed immediate offsets in the 401 * instructions. If we can put the most commonly accessed globals 402 * in a special 4K span of memory addressed by the GP register, then 403 * we can access those values in a single instruction, saving both 404 * codespace and runtime. 405 * 406 * Since these immediate offsets are signed, place gp 0x800 past the 407 * beginning of .sdata so that we can use both positive and negative 408 * offsets. 409 */ 410 . = ALIGN(8); 411 PROVIDE (__global_pointer$ = . + 0x800); 412#endif 413 414 *(.sdata .sdata.* .gnu.linkonce.s.*) 415 416/* Located in generated directory. This file is populated by the 417 * zephyr_linker_sources() Cmake function. 418 */ 419#include <snippets-rwdata.ld> 420 421#ifdef CONFIG_CODE_DATA_RELOCATION 422#include <linker_sram_data_relocate.ld> 423#endif 424 425 __data_end = .; 426 427 } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 428 __data_size = __data_end - __data_start; 429 __data_load_start = LOADADDR(_DATA_SECTION_NAME); 430 431 __data_region_load_start = LOADADDR(_DATA_SECTION_NAME); 432 433#include <zephyr/linker/common-ram.ld> 434#include <zephyr/linker/kobject-data.ld> 435#include <zephyr/linker/cplusplus-ram.ld> 436 437/* Located in generated directory. This file is populated by the 438 * zephyr_linker_sources() Cmake function. 439 */ 440#include <snippets-data-sections.ld> 441 442 __data_region_end = .; 443 444 SECTION_DATA_PROLOGUE(.h2ram_pool,(NOLOAD),) 445 { 446 /* 447 * Since __sha256_ram_block section must in the first 4KB, 448 * h2ram_pool section is no longer included first inside the 449 * RAMABLE_REGION. 450 * Append h2ram_pool section at the end of used memory, so gap 451 * due to alignment is still available for newly added variables 452 */ 453 . = ALIGN(0x1000); 454 _h2ram_pool_start = .; 455 KEEP(*(.h2ram_pool)) 456 _h2ram_pool_end = .; 457 } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) 458 _h2ram_pool_size = ABSOLUTE(_h2ram_pool_end - _h2ram_pool_start); 459 460 __kernel_ram_end = .; 461 __kernel_ram_size = __kernel_ram_end - __kernel_ram_start; 462 463/* Located in generated directory. This file is populated by the 464 * zephyr_linker_sources() Cmake function. 465 */ 466#include <snippets-sections.ld> 467 468#define LAST_RAM_ALIGN MPU_MIN_SIZE_ALIGN 469 470#include <zephyr/linker/ram-end.ld> 471 472 GROUP_END(RAMABLE_REGION) 473 474#include <zephyr/linker/debug-sections.ld> 475 476 /DISCARD/ : { *(.note.GNU-stack) } 477 478 SECTION_PROLOGUE(.riscv.attributes, 0,) 479 { 480 KEEP(*(.riscv.attributes)) 481 KEEP(*(.gnu.attributes)) 482 } 483 484 /* Sections generated from 'zephyr,memory-region' nodes */ 485 LINKER_DT_SECTIONS() 486 487/* Because ROMABLE_REGION != RAMABLE_REGION in XIP-system, it is valid 488 * to set __rom_region_end symbol at the end of linker script and 489 * doesn't mistakenly contain the RAMABLE_REGION in it. 490 */ 491#ifdef CONFIG_XIP 492/* Must be last in romable region */ 493SECTION_PROLOGUE(.last_section,(NOLOAD),) 494{ 495} GROUP_LINK_IN(ROMABLE_REGION) 496 497/* To provide the image size as a const expression, 498 * calculate this value here. */ 499__rom_region_end = LOADADDR(.last_section); 500__rom_region_size = __rom_region_end - __rom_region_start; 501#endif 502 503} 504