1/*
2 * Copyright (c) 2019 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_int5_lit :
82	org = INTLEVEL5_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
83        len = MEM_VECT_LIT_SIZE
84  vector_int5_text :
85	org = INTLEVEL5_VECTOR_PADDR_SRAM,
86        len = MEM_VECT_TEXT_SIZE
87  vector_int6_lit :
88	org = INTLEVEL6_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
89        len = MEM_VECT_LIT_SIZE
90  vector_int6_text :
91	org = INTLEVEL6_VECTOR_PADDR_SRAM,
92        len = MEM_VECT_TEXT_SIZE
93  vector_int7_lit :
94	org = INTLEVEL7_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
95        len = MEM_VECT_LIT_SIZE
96  vector_int7_text :
97	org = INTLEVEL7_VECTOR_PADDR_SRAM,
98        len = MEM_VECT_TEXT_SIZE
99  vector_kernel_lit :
100	org = KERNEL_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
101        len = MEM_VECT_LIT_SIZE
102  vector_kernel_text :
103	org = KERNEL_VECTOR_PADDR_SRAM,
104        len = MEM_VECT_TEXT_SIZE
105  vector_user_lit :
106	org = USER_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
107        len = MEM_VECT_LIT_SIZE
108  vector_user_text :
109	org = USER_VECTOR_PADDR_SRAM,
110        len = MEM_VECT_TEXT_SIZE
111  vector_double_lit :
112	org = DOUBLEEXC_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
113        len = MEM_VECT_LIT_SIZE
114  vector_double_text :
115	org = DOUBLEEXC_VECTOR_PADDR_SRAM,
116        len = MEM_VECT_TEXT_SIZE
117  imr :
118        org = IMR_BOOT_LDR_TEXT_ENTRY_BASE,
119        len = 0x100000
120  RAM :
121	org = RAM_BASE,
122	len = RAM_SIZE
123#ifdef CONFIG_KERNEL_COHERENCE
124  ucram :
125	org = RPO_SET(RAM_BASE, CONFIG_XTENSA_UNCACHED_REGION),
126	len = RAM_SIZE
127#endif
128#ifdef CONFIG_GEN_ISR_TABLES
129  IDT_LIST :
130	org = IDT_BASE,
131	len = IDT_SIZE
132#endif
133  lpram :
134	org = LP_SRAM_BASE,
135	len = LP_SRAM_SIZE
136  noload :
137        org = NOLOAD_BASE,
138        len = NOLOAD_SIZE
139}
140
141SECTIONS {
142
143  /* Boot loader code in IMR memory */
144  .imr : {
145    _imr_start = .;
146    /* Entry point MUST be here per external configuration */
147    KEEP (*(.boot_entry.text))
148    *(.imr .imr.*)
149    _imr_end = .;
150  } >imr
151
152  /* Boot loader data.  Note that rimage seems to want this
153   * page-aligned or it will throw an error, not sure why since all
154   * the ROM cares about is a contiguous region.  And it's
155   * particularly infuriating as it precludes linker .rodata next to
156   * .text.
157   */
158  .imrdata : ALIGN(4096) {
159    *(.imrdata .imrdata.*)
160  } >imr
161
162   .WindowVectors.text : {
163    _WindowVectors_text_start = .;
164    KEEP (*(.WindowVectors.text))
165    _WindowVectors_text_end = .;
166  } >vector_base_text
167  .Level2InterruptVector.literal : {
168    _Level2InterruptVector_literal_start = .;
169    *(.Level2InterruptVector.literal)
170    _Level2InterruptVector_literal_end = .;
171  } >vector_int2_lit
172  .Level2InterruptVector.text : {
173    _Level2InterruptVector_text_start = .;
174    KEEP (*(.Level2InterruptVector.text))
175    _Level2InterruptVector_text_end = .;
176  } >vector_int2_text
177  .Level3InterruptVector.literal : {
178    _Level3InterruptVector_literal_start = .;
179    *(.Level3InterruptVector.literal)
180    _Level3InterruptVector_literal_end = .;
181  } >vector_int3_lit
182  .Level3InterruptVector.text : {
183    _Level3InterruptVector_text_start = .;
184    KEEP (*(.Level3InterruptVector.text))
185    _Level3InterruptVector_text_end = .;
186  } >vector_int3_text
187  .Level4InterruptVector.literal : {
188    _Level4InterruptVector_literal_start = .;
189    *(.Level4InterruptVector.literal)
190    _Level4InterruptVector_literal_end = .;
191  } >vector_int4_lit
192  .Level4InterruptVector.text : {
193    _Level4InterruptVector_text_start = .;
194    KEEP (*(.Level4InterruptVector.text))
195    _Level4InterruptVector_text_end = .;
196  } >vector_int4_text
197  .Level5InterruptVector.literal : {
198    _Level5InterruptVector_literal_start = .;
199    *(.Level5InterruptVector.literal)
200    _Level5InterruptVector_literal_end = .;
201  } >vector_int5_lit
202  .Level5InterruptVector.text : {
203    _Level5InterruptVector_text_start = .;
204    KEEP (*(.Level5InterruptVector.text))
205    _Level5InterruptVector_text_end = .;
206  } >vector_int5_text
207  .DebugExceptionVector.literal : {
208    _DebugExceptionVector_literal_start = .;
209    *(.DebugExceptionVector.literal)
210    _DebugExceptionVector_literal_end = .;
211  } >vector_int6_lit
212  .DebugExceptionVector.text : {
213    _DebugExceptionVector_text_start = .;
214    KEEP (*(.DebugExceptionVector.text))
215    _DebugExceptionVector_text_end = .;
216  } >vector_int6_text
217  .NMIExceptionVector.literal : {
218    _NMIExceptionVector_literal_start = .;
219    *(.NMIExceptionVector.literal)
220    _NMIExceptionVector_literal_end = .;
221  } >vector_int7_lit
222  .NMIExceptionVector.text : {
223    _NMIExceptionVector_text_start = .;
224    KEEP (*(.NMIExceptionVector.text))
225    _NMIExceptionVector_text_end = .;
226  } >vector_int7_text
227  .KernelExceptionVector.literal : {
228    _KernelExceptionVector_literal_start = .;
229    *(.KernelExceptionVector.literal)
230    _KernelExceptionVector_literal_end = .;
231  } >vector_kernel_lit
232  .KernelExceptionVector.text : {
233    _KernelExceptionVector_text_start = .;
234    KEEP (*(.KernelExceptionVector.text))
235    _KernelExceptionVector_text_end = .;
236  } >vector_kernel_text
237  .UserExceptionVector.literal : {
238    _UserExceptionVector_literal_start = .;
239    *(.UserExceptionVector.literal)
240    _UserExceptionVector_literal_end = .;
241  } >vector_user_lit
242  .UserExceptionVector.text : {
243    _UserExceptionVector_text_start = .;
244    KEEP (*(.UserExceptionVector.text))
245    _UserExceptionVector_text_end = .;
246  } >vector_user_text
247  .DoubleExceptionVector.literal : {
248    _DoubleExceptionVector_literal_start = .;
249    *(.DoubleExceptionVector.literal)
250    _DoubleExceptionVector_literal_end = .;
251  } >vector_double_lit
252  .DoubleExceptionVector.text : {
253    _DoubleExceptionVector_text_start = .;
254    KEEP (*(.DoubleExceptionVector.text))
255    _DoubleExceptionVector_text_end = .;
256  } >vector_double_text
257
258#ifdef CONFIG_CODE_DATA_RELOCATION
259#include <linker_relocate.ld>
260#endif
261
262  .text : {
263    __text_region_start = .;
264    *(.iram1 .iram1.*)
265    *(.entry.text)
266    *(.init.literal)
267    *(.iram0.text)
268    KEEP(*(.init))
269    KEEP(*(.lps_vector))
270    *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
271    *(.fini.literal)
272    KEEP(*(.fini))
273    *(.gnu.version)
274    __text_region_end = .;
275  } >RAM
276
277  .rodata : ALIGN(4096)
278  {
279    __rodata_region_start = .;
280    *(.rodata)
281    *(.rodata.*)
282    *(.gnu.linkonce.r.*)
283    *(.rodata1)
284
285    . = ALIGN(4);
286    #include <snippets-rodata.ld>
287
288    __XT_EXCEPTION_TABLE__ = .;
289    KEEP (*(.xt_except_table))
290    KEEP (*(.gcc_except_table .gcc_except_table.*))
291    *(.gnu.linkonce.e.*)
292    *(.gnu.version_r)
293    KEEP (*(.eh_frame))
294    KEEP (*crtbegin.o(.ctors))
295    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
296    KEEP (*(SORT(.ctors.*)))
297    KEEP (*(.ctors))
298    KEEP (*crtbegin.o(.dtors))
299    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
300    KEEP (*(SORT(.dtors.*)))
301    KEEP (*(.dtors))
302    __XT_EXCEPTION_DESCS__ = .;
303    *(.xt_except_desc)
304    *(.gnu.linkonce.h.*)
305    __XT_EXCEPTION_DESCS_END__ = .;
306    *(.xt_except_desc_end)
307    *(.dynamic)
308    *(.gnu.version_d)
309    _image_ram_start = .;
310    _bss_table_start = .;
311    LONG(_bss_start)
312    LONG(_bss_end)
313    _bss_table_end = .;
314    __rodata_region_end = .;
315  } >RAM
316
317  .module_init : {
318    _module_init_start = .;
319    *(*.initcall)
320    _module_init_end = .;
321  } >RAM
322
323#define RAMABLE_REGION RAM
324#define ROMABLE_REGION RAM
325#include <zephyr/linker/common-rom.ld>
326/* Located in generated directory. This file is populated by calling
327 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs.
328 */
329#include <snippets-rom-sections.ld>
330
331  .fw_ready : {
332    KEEP(*(".fw_ready"));
333    KEEP (*(.fw_ready_metadata))
334  } >RAM
335
336  .noinit SEGSTART_UNCACHED : {
337    *(.noinit)
338    *(.noinit.*)
339  } >ucram
340
341  .data SEGSTART_UNCACHED : {
342    __data_start = .;
343    *(.data)
344    *(.data.*)
345    *(.gnu.linkonce.d.*)
346    KEEP(*(.gnu.linkonce.d.*personality*))
347    *(.data1)
348    *(.sdata)
349    *(.sdata.*)
350    *(.gnu.linkonce.s.*)
351    *(.sdata2)
352    *(.sdata2.*)
353    *(.gnu.linkonce.s2.*)
354    KEEP(*(.jcr))
355    _trace_ctx_start = ABSOLUTE(.);
356    *(.trace_ctx)
357    _trace_ctx_end = ABSOLUTE(.);
358    *(.gna_model)
359#ifdef CONFIG_CODE_DATA_RELOCATION
360#include <linker_sram_data_relocate.ld>
361#endif
362    __data_end = .;
363  } >ucram
364
365  .lit4 SEGSTART_CACHED : {
366    _lit4_start = .;
367    *(*.lit4)
368    *(.lit4.*)
369    *(.gnu.linkonce.lit4.*)
370    _lit4_end = .;
371  } >RAM
372
373/* These values need to change in our scheme, where the common-ram
374 * sections need to be linked in safe/uncached memory but common-rom
375 * wants to use the cache
376 */
377. = SEGSTART_UNCACHED;
378#undef RAMABLE_REGION
379#undef ROMABLE_REGION
380#define RAMABLE_REGION ucram
381#define ROMABLE_REGION ucram
382
383#include <zephyr/linker/common-ram.ld>
384
385  .tm_clone_table : {
386    *(.tm_clone_table)
387  } >RAM
388
389  /* This section is cached.  By default it contains only declared
390  * thread stacks, but applications can put symbols here too.
391  */
392  .cached SEGSTART_CACHED : {
393    _cached_start = .;
394    *(.cached .cached.*)
395    _cached_end = .;
396  } >RAM
397
398  /* Rimage requires 4k alignment between "DATA" and "BSS", can't do
399   * this in the section declaration below because we're also changing
400   * cacheability and that leaves a gap in the image large enough for
401   * binutils to decide to warn about (no way to turn that off, it
402   * seems, --warn-section-align is on by default)
403   */
404  . = ALIGN(4096);
405
406  .bss SEGSTART_UNCACHED (NOLOAD) :
407  {
408    _bss_start = .;
409    *(.dynsbss)
410    *(.sbss)
411    *(.sbss.*)
412    *(.gnu.linkonce.sb.*)
413    *(.scommon)
414    *(.sbss2)
415    *(.sbss2.*)
416    *(.gnu.linkonce.sb2.*)
417    *(.dynbss)
418    *(.bss)
419    *(.bss.*)
420    *(.gnu.linkonce.b.*)
421    *(COMMON)
422#ifdef CONFIG_CODE_DATA_RELOCATION
423#include <linker_sram_bss_relocate.ld>
424#endif
425    . = ALIGN(8);
426    _bss_end = .;
427  } >ucram
428
429  /* Heap start and end markers.  Mostly unused, though newlib likes them */
430  . = SEGSTART_UNCACHED;
431  _end = ALIGN(8);
432  . = L2_SRAM_BASE + L2_SRAM_SIZE;
433  . = SEGSTART_UNCACHED;
434  _heap_sentry = .;
435
436  /* dma buffers */
437  .lpbuf (NOLOAD): {
438    _dma_buf_start = .;
439    *(.dma_buffers)
440    _dma_buf_end = .;
441    _image_ram_end = .;
442  } >lpram
443
444  /* Non-loadable sections below.  Back to cached memory so
445   * the cache remap script doesn't try to move them around needlessly.
446   */
447  . = SEGSTART_CACHED;
448
449  /* rimage module manifest headers */
450  .module.boot : { KEEP(*(.module.boot)) } >noload
451  .module.main : { KEEP(*(.module.main)) } >noload
452
453 .static_uuid_entries : {
454    *(*.static_uuids)
455  } >noload
456
457  .static_log_entries : {
458    *(*.static_log*)
459  } >noload
460
461  /* This is the "extended manifest" data (mostly versioning stuff)
462   * emitted by SOF and inspected by the kernel driver.  It doesn't
463   * appear directly in the image, but rimage will parse and repack
464   * this into the output file header, so requires this be present
465   * even if empty.  Alignment and padding to 16 bytes is required,
466   * otherwise rimage will complain about the size being wrong (which
467   * sounds like a struct should be declared packed somewhere...)
468   */
469  .fw_metadata : ALIGN(16) {
470    KEEP (*(.fw_metadata))
471    . = ALIGN(16);
472  } >noload
473
474
475#include <snippets-sections.ld>
476
477#include <zephyr/linker/debug-sections.ld>
478
479  .xtensa.info 0 : { *(.xtensa.info) }
480  .xt.insn 0 : {
481    KEEP (*(.xt.insn))
482    KEEP (*(.gnu.linkonce.x.*))
483  }
484  .xt.prop 0 : {
485    KEEP (*(.xt.prop))
486    KEEP (*(.xt.prop.*))
487    KEEP (*(.gnu.linkonce.prop.*))
488  }
489  .xt.lit 0 : {
490    KEEP (*(.xt.lit))
491    KEEP (*(.xt.lit.*))
492    KEEP (*(.gnu.linkonce.p.*))
493  }
494  .xt.profile_range 0 : {
495    KEEP (*(.xt.profile_range))
496    KEEP (*(.gnu.linkonce.profile_range.*))
497  }
498  .xt.profile_ranges 0 : {
499    KEEP (*(.xt.profile_ranges))
500    KEEP (*(.gnu.linkonce.xt.profile_ranges.*))
501  }
502  .xt.profile_files 0 : {
503    KEEP (*(.xt.profile_files))
504    KEEP (*(.gnu.linkonce.xt.profile_files.*))
505  }
506
507#ifdef CONFIG_GEN_ISR_TABLES
508#include <zephyr/linker/intlist.ld>
509#endif
510
511#ifdef CONFIG_LLEXT
512#include <zephyr/linker/llext-sections.ld>
513#endif
514}
515