1/* 2 * Copyright (c) 2022 Intel Corporation 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7/** 8 * @file 9 * @brief Linker command/script file 10 * 11 * Linker script for the intel_apl_adsp platform 12 */ 13 14OUTPUT_ARCH(xtensa) 15 16#include <zephyr/devicetree.h> 17#include <xtensa/config/core-isa.h> 18#include <zephyr/linker/sections.h> 19#include <adsp-vectors.h> 20#include <adsp_memory.h> 21 22#include <zephyr/linker/linker-defs.h> 23#include <zephyr/linker/linker-tool.h> 24 25ENTRY(rom_entry); 26 27/* DSP RAM regions (all of them) are mapped twice on the DSP. One 28 * mapping is set up to bypass the L1 cache, so it must be used when 29 * multiprocessor coherence is desired, where the latter mapping is 30 * best used for processor-local data (e.g. stacks) or shared data 31 * that is managed with explicit cache flush/invalidate operations. 32 * 33 * These macros will set up a segment start address correctly, 34 * including alignment to a cache line. Be sure to also emit the 35 * section to ">ram" or ">ucram" as appropriate, to prevent the linker 36 * from filling in 512MB of sparse zeros. 37 */ 38#ifdef CONFIG_KERNEL_COHERENCE 39#define RPO_SET(addr, reg) ((addr & 0x1fffffff) | (reg << 29)) 40#define SEGSTART_CACHED RPO_SET(ALIGN(64), CONFIG_XTENSA_CACHED_REGION) 41#define SEGSTART_UNCACHED RPO_SET(ALIGN(64), CONFIG_XTENSA_UNCACHED_REGION) 42#else 43#define SEGSTART_CACHED . 44#define SEGSTART_UNCACHED . 45#define ucram ram 46#endif 47 48/* intlist.ld needs an IDT_LIST memory region */ 49#define IDT_BASE 0xe0000000 50#define IDT_SIZE 0x2000 51 52/* rimage module sections are C struct data, and thus flagged ALLOC. 53 * The xcc linker demands they be in a declared memory region even if 54 * the enclosing output section is (NOLOAD). Put them here. 55 */ 56#define NOLOAD_BASE 0x20000 57#define NOLOAD_SIZE 0x100000 58 59MEMORY { 60 vector_base_text : 61 org = VECBASE_RESET_PADDR_SRAM, 62 len = MEM_VECBASE_LIT_SIZE 63 vector_int2_lit : 64 org = INTLEVEL2_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE, 65 len = MEM_VECT_LIT_SIZE 66 vector_int2_text : 67 org = INTLEVEL2_VECTOR_PADDR_SRAM, 68 len = MEM_VECT_TEXT_SIZE 69 vector_int3_lit : 70 org = INTLEVEL3_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE, 71 len = MEM_VECT_LIT_SIZE 72 vector_int3_text : 73 org = INTLEVEL3_VECTOR_PADDR_SRAM, 74 len = MEM_VECT_TEXT_SIZE 75 vector_int4_lit : 76 org = INTLEVEL4_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE, 77 len = MEM_VECT_LIT_SIZE 78 vector_int4_text : 79 org = INTLEVEL4_VECTOR_PADDR_SRAM, 80 len = MEM_VECT_TEXT_SIZE 81 vector_int7_lit : 82 org = INTLEVEL7_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE, 83 len = MEM_VECT_LIT_SIZE 84 vector_int7_text : 85 org = INTLEVEL7_VECTOR_PADDR_SRAM, 86 len = MEM_VECT_TEXT_SIZE 87 vector_kernel_lit : 88 org = KERNEL_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE, 89 len = MEM_VECT_LIT_SIZE 90 vector_kernel_text : 91 org = KERNEL_VECTOR_PADDR_SRAM, 92 len = MEM_VECT_TEXT_SIZE 93 vector_user_lit : 94 org = USER_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE, 95 len = MEM_VECT_LIT_SIZE 96 vector_user_text : 97 org = USER_VECTOR_PADDR_SRAM, 98 len = MEM_VECT_TEXT_SIZE 99 vector_double_lit : 100 org = DOUBLEEXC_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE, 101 len = MEM_VECT_LIT_SIZE 102 vector_double_text : 103 org = DOUBLEEXC_VECTOR_PADDR_SRAM, 104 len = MEM_VECT_TEXT_SIZE 105 imr : 106 org = IMR_BOOT_LDR_TEXT_ENTRY_BASE, 107 len = 0x100000 108 ram : 109 org = RAM_BASE, 110 len = RAM_SIZE 111#ifdef CONFIG_KERNEL_COHERENCE 112 ucram : 113 org = RPO_SET(RAM_BASE, CONFIG_XTENSA_UNCACHED_REGION), 114 len = RAM_SIZE 115#endif 116#ifdef CONFIG_GEN_ISR_TABLES 117 IDT_LIST : 118 org = IDT_BASE, 119 len = IDT_SIZE 120#endif 121 lpram : 122 org = LP_SRAM_BASE, 123 len = LP_SRAM_SIZE 124 noload : 125 org = NOLOAD_BASE, 126 len = NOLOAD_SIZE 127} 128 129SECTIONS { 130 131 /* Boot loader code in IMR memory */ 132 .imr : { 133 _imr_start = .; 134 /* Entry point MUST be here per external configuration */ 135 KEEP (*(.boot_entry.text)) 136 *(.imr .imr.*) 137 } >imr 138 139 /* Boot loader data. Note that rimage seems to want this 140 * page-aligned or it will throw an error, not sure why since all 141 * the ROM cares about is a contiguous region. And it's 142 * particularly infuriating as it precludes linker .rodata next to 143 * .text. 144 */ 145 .imrdata : ALIGN(4096) { 146 *(.imrdata .imrdata.*) 147 _imr_end = .; 148 } >imr 149 150 .WindowVectors.text : { 151 _WindowVectors_text_start = .; 152 KEEP (*(.WindowVectors.text)) 153 _WindowVectors_text_end = .; 154 } >vector_base_text 155 .Level2InterruptVector.literal : { 156 _Level2InterruptVector_literal_start = .; 157 *(.Level2InterruptVector.literal) 158 _Level2InterruptVector_literal_end = .; 159 } >vector_int2_lit 160 .Level2InterruptVector.text : { 161 _Level2InterruptVector_text_start = .; 162 KEEP (*(.Level2InterruptVector.text)) 163 _Level2InterruptVector_text_end = .; 164 } >vector_int2_text 165 .Level3InterruptVector.literal : { 166 _Level3InterruptVector_literal_start = .; 167 *(.Level3InterruptVector.literal) 168 _Level3InterruptVector_literal_end = .; 169 } >vector_int3_lit 170 .Level3InterruptVector.text : { 171 _Level3InterruptVector_text_start = .; 172 KEEP (*(.Level3InterruptVector.text)) 173 _Level3InterruptVector_text_end = .; 174 } >vector_int3_text 175 .Level4InterruptVector.literal : { 176 _Level4InterruptVector_literal_start = .; 177 *(.Level4InterruptVector.literal) 178 _Level4InterruptVector_literal_end = .; 179 } >vector_int4_lit 180 .Level4InterruptVector.text : { 181 _Level4InterruptVector_text_start = .; 182 KEEP (*(.Level4InterruptVector.text)) 183 _Level4InterruptVector_text_end = .; 184 } >vector_int4_text 185 .DebugExceptionVector.literal : { 186 _DebugExceptionVector_literal_start = .; 187 *(.DebugExceptionVector.literal) 188 _DebugExceptionVector_literal_end = .; 189 } >vector_int4_lit 190 .DebugExceptionVector.text : { 191 _DebugExceptionVector_text_start = .; 192 KEEP (*(.DebugExceptionVector.text)) 193 _DebugExceptionVector_text_end = .; 194 } >vector_int4_text 195 .NMIExceptionVector.literal : { 196 _NMIExceptionVector_literal_start = .; 197 *(.NMIExceptionVector.literal) 198 _NMIExceptionVector_literal_end = .; 199 } >vector_int7_lit 200 .NMIExceptionVector.text : { 201 _NMIExceptionVector_text_start = .; 202 KEEP (*(.NMIExceptionVector.text)) 203 _NMIExceptionVector_text_end = .; 204 } >vector_int7_text 205 .KernelExceptionVector.literal : { 206 _KernelExceptionVector_literal_start = .; 207 *(.KernelExceptionVector.literal) 208 _KernelExceptionVector_literal_end = .; 209 } >vector_kernel_lit 210 .KernelExceptionVector.text : { 211 _KernelExceptionVector_text_start = .; 212 KEEP (*(.KernelExceptionVector.text)) 213 _KernelExceptionVector_text_end = .; 214 } >vector_kernel_text 215 .UserExceptionVector.literal : { 216 _UserExceptionVector_literal_start = .; 217 *(.UserExceptionVector.literal) 218 _UserExceptionVector_literal_end = .; 219 } >vector_user_lit 220 .UserExceptionVector.text : { 221 _UserExceptionVector_text_start = .; 222 KEEP (*(.UserExceptionVector.text)) 223 _UserExceptionVector_text_end = .; 224 } >vector_user_text 225 .DoubleExceptionVector.literal : { 226 _DoubleExceptionVector_literal_start = .; 227 *(.DoubleExceptionVector.literal) 228 _DoubleExceptionVector_literal_end = .; 229 } >vector_double_lit 230 .DoubleExceptionVector.text : { 231 _DoubleExceptionVector_text_start = .; 232 KEEP (*(.DoubleExceptionVector.text)) 233 _DoubleExceptionVector_text_end = .; 234 } >vector_double_text 235 236 .text : { 237 __text_region_start = .; 238 *(.iram1 .iram1.*) 239 *(.entry.text) 240 *(.init.literal) 241 *(.iram0.text) 242 KEEP(*(.init)) 243 KEEP(*(.lps_vector)) 244 *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 245 *(.fini.literal) 246 KEEP(*(.fini)) 247 *(.gnu.version) 248 __text_region_end = .; 249 } >ram 250 251 .rodata : ALIGN(4096) 252 { 253 __rodata_region_start = .; 254 *(.rodata) 255 *(.rodata.*) 256 *(.gnu.linkonce.r.*) 257 *(.rodata1) 258 259 . = ALIGN(4); 260 #include <snippets-rodata.ld> 261 262 __XT_EXCEPTION_TABLE__ = .; 263 KEEP (*(.xt_except_table)) 264 KEEP (*(.gcc_except_table .gcc_except_table.*)) 265 *(.gnu.linkonce.e.*) 266 *(.gnu.version_r) 267 KEEP (*(.eh_frame)) 268 KEEP (*crtbegin.o(.ctors)) 269 KEEP (*crtbegin.o(.dtors)) 270 KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) 271 KEEP (*(SORT(.dtors.*))) 272 KEEP (*(.dtors)) 273 __XT_EXCEPTION_DESCS__ = .; 274 *(.xt_except_desc) 275 *(.gnu.linkonce.h.*) 276 __XT_EXCEPTION_DESCS_END__ = .; 277 *(.xt_except_desc_end) 278 *(.dynamic) 279 *(.gnu.version_d) 280 _image_ram_start = .; 281 _bss_table_start = .; 282 LONG(_bss_start) 283 LONG(_bss_end) 284 _bss_table_end = .; 285 } >ram 286 287 .module_init : { 288 _module_init_start = .; 289 *(*.initcall) 290 _module_init_end = .; 291 } >ram 292 293#define RAMABLE_REGION ram 294#define ROMABLE_REGION ram 295#include <zephyr/linker/common-rom.ld> 296 __rodata_region_end = .; 297 298 .fw_ready : { 299 KEEP(*(".fw_ready")); 300 KEEP (*(.fw_ready_metadata)) 301 } >ram 302 303 .noinit SEGSTART_UNCACHED : { 304 *(.noinit) 305 *(.noinit.*) 306 } >ucram 307 308 .data SEGSTART_UNCACHED : { 309 __data_start = .; 310 *(.data) 311 *(.data.*) 312 *(.gnu.linkonce.d.*) 313 KEEP(*(.gnu.linkonce.d.*personality*)) 314 *(.data1) 315 *(.sdata) 316 *(.sdata.*) 317 *(.gnu.linkonce.s.*) 318 *(.sdata2) 319 *(.sdata2.*) 320 *(.gnu.linkonce.s2.*) 321 KEEP(*(.jcr)) 322 _trace_ctx_start = ABSOLUTE(.); 323 *(.trace_ctx) 324 _trace_ctx_end = ABSOLUTE(.); 325 *(.gna_model) 326 __data_end = .; 327 } >ucram 328 329 .lit4 SEGSTART_CACHED : { 330 _lit4_start = .; 331 *(*.lit4) 332 *(.lit4.*) 333 *(.gnu.linkonce.lit4.*) 334 _lit4_end = .; 335 } >ram 336 337/* These values need to change in our scheme, where the common-ram 338 * sections need to be linked in safe/uncached memory but common-rom 339 * wants to use the cache 340 */ 341. = SEGSTART_UNCACHED; 342#undef RAMABLE_REGION 343#undef ROMABLE_REGION 344#define RAMABLE_REGION ucram 345#define ROMABLE_REGION ucram 346 347#include <zephyr/linker/common-ram.ld> 348 349 .tm_clone_table : { 350 *(.tm_clone_table) 351 } >ram 352 353 /* This section is cached. By default it contains only declared 354 * thread stacks, but applications can put symbols here too. 355 */ 356 .cached SEGSTART_CACHED : { 357 _cached_start = .; 358 *(.cached .cached.*) 359 _cached_end = .; 360 } >ram 361 362 /* Rimage requires 4k alignment between "DATA" and "BSS", can't do 363 * this in the section declaration below because we're also changing 364 * cacheability and that leaves a gap in the image large enough for 365 * binutils to decide to warn about (no way to turn that off, it 366 * seems, --warn-section-align is on by default) 367 */ 368 . = ALIGN(4096); 369 370 .bss SEGSTART_UNCACHED (NOLOAD) : 371 { 372 _bss_start = .; 373 *(.dynsbss) 374 *(.sbss) 375 *(.sbss.*) 376 *(.gnu.linkonce.sb.*) 377 *(.scommon) 378 *(.sbss2) 379 *(.sbss2.*) 380 *(.gnu.linkonce.sb2.*) 381 *(.dynbss) 382 *(.bss) 383 *(.bss.*) 384 *(.gnu.linkonce.b.*) 385 *(COMMON) 386 . = ALIGN(8); 387 _bss_end = .; 388 } >ucram 389 390 . = SEGSTART_UNCACHED; 391 _end = ALIGN(8); 392 393 /* Heap start and end markers. Used to reserve system heap memory. */ 394 .heap_mem SEGSTART_UNCACHED (NOLOAD) : 395 { 396 _heap_start = .; 397 *(.heap_mem) 398 } >ucram 399 400 .unused_ram_start_marker SEGSTART_CACHED (NOLOAD) : 401 { 402 . = ALIGN(4096); 403 _unused_ram_start_marker = .; 404 *(.unused_ram_start_marker) 405 *(.unused_ram_start_marker.*) 406 z_mapped_end = .; 407 } >ram 408 409 /* Heap start and end markers. Used with libc malloc code. */ 410 . = SEGSTART_UNCACHED; 411 _end = ALIGN(8); 412 . = SEGSTART_CACHED; 413 . = L2_SRAM_BASE + L2_SRAM_SIZE; 414 . = SEGSTART_UNCACHED; 415 _heap_end = .; 416 _heap_sentry = .; 417 418 /* dma buffers */ 419 .lpbuf (NOLOAD): { 420 _dma_buf_start = .; 421 *(.dma_buffers) 422 _dma_buf_end = .; 423 _image_ram_end = .; 424 } >lpram 425 426 /* Non-loadable sections below. Back to cached memory so 427 * the cache remap script doesn't try to move them around needlessly. 428 */ 429 . = SEGSTART_CACHED; 430 431 /* rimage module manifest headers */ 432 .module.boot : { KEEP(*(.module.boot)) } >noload 433 .module.main : { KEEP(*(.module.main)) } >noload 434 435 .static_uuid_entries : { 436 *(*.static_uuids) 437 } >noload 438 439 .static_log_entries : { 440 *(*.static_log*) 441 } >noload 442 443 /* This is the "extended manifest" data (mostly versioning stuff) 444 * emitted by SOF and inspected by the kernel driver. It doesn't 445 * appear directly in the image, but rimage will parse and repack 446 * this into the output file header, so requires this be present 447 * even if empty. Alignment and padding to 16 bytes is required, 448 * otherwise rimage will complain about the size being wrong (which 449 * sounds like a struct should be declared packed somewhere...) 450 */ 451 .fw_metadata : ALIGN(16) { 452 KEEP (*(.fw_metadata)) 453 . = ALIGN(16); 454 } >noload 455 456#include <snippets-sections.ld> 457 458#include <zephyr/linker/debug-sections.ld> 459 460 /DISCARD/ : { *(.note.GNU-stack) } 461 462 .xtensa.info 0 : { *(.xtensa.info) } 463 .xt.insn 0 : { 464 KEEP (*(.xt.insn)) 465 KEEP (*(.gnu.linkonce.x.*)) 466 } 467 .xt.prop 0 : { 468 KEEP (*(.xt.prop)) 469 KEEP (*(.xt.prop.*)) 470 KEEP (*(.gnu.linkonce.prop.*)) 471 } 472 .xt.lit 0 : { 473 KEEP (*(.xt.lit)) 474 KEEP (*(.xt.lit.*)) 475 KEEP (*(.gnu.linkonce.p.*)) 476 } 477 .xt.profile_range 0 : { 478 KEEP (*(.xt.profile_range)) 479 KEEP (*(.gnu.linkonce.profile_range.*)) 480 } 481 .xt.profile_ranges 0 : { 482 KEEP (*(.xt.profile_ranges)) 483 KEEP (*(.gnu.linkonce.xt.profile_ranges.*)) 484 } 485 .xt.profile_files 0 : { 486 KEEP (*(.xt.profile_files)) 487 KEEP (*(.gnu.linkonce.xt.profile_files.*)) 488 } 489 490#ifdef CONFIG_GEN_ISR_TABLES 491#include <zephyr/linker/intlist.ld> 492#endif 493} 494