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