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
327  .fw_ready : {
328    KEEP(*(".fw_ready"));
329    KEEP (*(.fw_ready_metadata))
330  } >RAM
331
332  .noinit SEGSTART_UNCACHED : {
333    *(.noinit)
334    *(.noinit.*)
335  } >ucram
336
337  .data SEGSTART_UNCACHED : {
338    __data_start = .;
339    *(.data)
340    *(.data.*)
341    *(.gnu.linkonce.d.*)
342    KEEP(*(.gnu.linkonce.d.*personality*))
343    *(.data1)
344    *(.sdata)
345    *(.sdata.*)
346    *(.gnu.linkonce.s.*)
347    *(.sdata2)
348    *(.sdata2.*)
349    *(.gnu.linkonce.s2.*)
350    KEEP(*(.jcr))
351    _trace_ctx_start = ABSOLUTE(.);
352    *(.trace_ctx)
353    _trace_ctx_end = ABSOLUTE(.);
354    *(.gna_model)
355#ifdef CONFIG_CODE_DATA_RELOCATION
356#include <linker_sram_data_relocate.ld>
357#endif
358    __data_end = .;
359  } >ucram
360
361  .lit4 SEGSTART_CACHED : {
362    _lit4_start = .;
363    *(*.lit4)
364    *(.lit4.*)
365    *(.gnu.linkonce.lit4.*)
366    _lit4_end = .;
367  } >RAM
368
369/* These values need to change in our scheme, where the common-ram
370 * sections need to be linked in safe/uncached memory but common-rom
371 * wants to use the cache
372 */
373. = SEGSTART_UNCACHED;
374#undef RAMABLE_REGION
375#undef ROMABLE_REGION
376#define RAMABLE_REGION ucram
377#define ROMABLE_REGION ucram
378
379#include <zephyr/linker/common-ram.ld>
380
381  .tm_clone_table : {
382    *(.tm_clone_table)
383  } >RAM
384
385  /* This section is cached.  By default it contains only declared
386  * thread stacks, but applications can put symbols here too.
387  */
388  .cached SEGSTART_CACHED : {
389    _cached_start = .;
390    *(.cached .cached.*)
391    _cached_end = .;
392  } >RAM
393
394  /* Rimage requires 4k alignment between "DATA" and "BSS", can't do
395   * this in the section declaration below because we're also changing
396   * cacheability and that leaves a gap in the image large enough for
397   * binutils to decide to warn about (no way to turn that off, it
398   * seems, --warn-section-align is on by default)
399   */
400  . = ALIGN(4096);
401
402  .bss SEGSTART_UNCACHED (NOLOAD) :
403  {
404    _bss_start = .;
405    *(.dynsbss)
406    *(.sbss)
407    *(.sbss.*)
408    *(.gnu.linkonce.sb.*)
409    *(.scommon)
410    *(.sbss2)
411    *(.sbss2.*)
412    *(.gnu.linkonce.sb2.*)
413    *(.dynbss)
414    *(.bss)
415    *(.bss.*)
416    *(.gnu.linkonce.b.*)
417    *(COMMON)
418#ifdef CONFIG_CODE_DATA_RELOCATION
419#include <linker_sram_bss_relocate.ld>
420#endif
421    . = ALIGN(8);
422    _bss_end = .;
423  } >ucram
424
425  /* Heap start and end markers.  Mostly unused, though newlib likes them */
426  . = SEGSTART_UNCACHED;
427  _end = ALIGN(8);
428  . = L2_SRAM_BASE + L2_SRAM_SIZE;
429  . = SEGSTART_UNCACHED;
430  _heap_sentry = .;
431
432  /* dma buffers */
433  .lpbuf (NOLOAD): {
434    _dma_buf_start = .;
435    *(.dma_buffers)
436    _dma_buf_end = .;
437    _image_ram_end = .;
438  } >lpram
439
440  /* Non-loadable sections below.  Back to cached memory so
441   * the cache remap script doesn't try to move them around needlessly.
442   */
443  . = SEGSTART_CACHED;
444
445  /* rimage module manifest headers */
446  .module.boot : { KEEP(*(.module.boot)) } >noload
447  .module.main : { KEEP(*(.module.main)) } >noload
448
449 .static_uuid_entries : {
450    *(*.static_uuids)
451  } >noload
452
453  .static_log_entries : {
454    *(*.static_log*)
455  } >noload
456
457  /* This is the "extended manifest" data (mostly versioning stuff)
458   * emitted by SOF and inspected by the kernel driver.  It doesn't
459   * appear directly in the image, but rimage will parse and repack
460   * this into the output file header, so requires this be present
461   * even if empty.  Alignment and padding to 16 bytes is required,
462   * otherwise rimage will complain about the size being wrong (which
463   * sounds like a struct should be declared packed somewhere...)
464   */
465  .fw_metadata : ALIGN(16) {
466    KEEP (*(.fw_metadata))
467    . = ALIGN(16);
468  } >noload
469
470
471#include <snippets-sections.ld>
472
473#include <zephyr/linker/debug-sections.ld>
474
475  .xtensa.info 0 : { *(.xtensa.info) }
476  .xt.insn 0 : {
477    KEEP (*(.xt.insn))
478    KEEP (*(.gnu.linkonce.x.*))
479  }
480  .xt.prop 0 : {
481    KEEP (*(.xt.prop))
482    KEEP (*(.xt.prop.*))
483    KEEP (*(.gnu.linkonce.prop.*))
484  }
485  .xt.lit 0 : {
486    KEEP (*(.xt.lit))
487    KEEP (*(.xt.lit.*))
488    KEEP (*(.gnu.linkonce.p.*))
489  }
490  .xt.profile_range 0 : {
491    KEEP (*(.xt.profile_range))
492    KEEP (*(.gnu.linkonce.profile_range.*))
493  }
494  .xt.profile_ranges 0 : {
495    KEEP (*(.xt.profile_ranges))
496    KEEP (*(.gnu.linkonce.xt.profile_ranges.*))
497  }
498  .xt.profile_files 0 : {
499    KEEP (*(.xt.profile_files))
500    KEEP (*(.gnu.linkonce.xt.profile_files.*))
501  }
502
503#ifdef CONFIG_GEN_ISR_TABLES
504#include <zephyr/linker/intlist.ld>
505#endif
506}
507