1/*
2 * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#include <zephyr/devicetree.h>
7#include <zephyr/linker/sections.h>
8#include <zephyr/linker/linker-defs.h>
9#include <zephyr/linker/linker-tool.h>
10
11#include "memory.h"
12
13/* Disable all romable LMA */
14#undef GROUP_DATA_LINK_IN
15#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion
16
17#define RAMABLE_REGION dram_seg
18#define RODATA_REGION  dram_seg
19#define ROMABLE_REGION dram_seg
20
21/* Global symbols required for espressif hal build */
22MEMORY
23{
24  iram_seg        (RX) : org = BOOTLOADER_IRAM_SEG_START,
25                         len = BOOTLOADER_IRAM_SEG_LEN
26  iram_loader_seg (RX) : org = BOOTLOADER_IRAM_LOADER_SEG_START,
27                         len = BOOTLOADER_IRAM_LOADER_SEG_LEN
28  dram_seg        (RW) : org = BOOTLOADER_DRAM_SEG_START,
29                         len = BOOTLOADER_DRAM_SEG_LEN
30
31#ifdef CONFIG_GEN_ISR_TABLES
32  IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000
33#endif
34}
35
36/*  Default entry point:  */
37ENTRY(CONFIG_KERNEL_ENTRY)
38
39SECTIONS
40{
41  .iram0.loader_text :
42  {
43    . = ALIGN (16);
44    _loader_text_start = ABSOLUTE(.);
45    *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
46
47    /* TODO: cross-segments calls in the libzephyr.a:device.* */
48
49    *libapp.a:flash_map_extended.*(.literal .text .literal.* .text.*)
50    *libzephyr.a:cbprintf_nano.*(.literal .text .literal.* .text.*)
51    *libzephyr.a:cpu.*(.literal .text .literal.* .text.*)
52    *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*)
53    *libzephyr.a:flash_map.*(.literal .text .literal.* .text.*)
54    *libzephyr.a:esp_rom_spiflash.*(.literal .text .literal.* .text.*)
55
56    *libzephyr.a:heap.*(.literal .text .literal.* .text.*)
57
58    *libkernel.a:kheap.*(.literal .text .literal.* .text.*)
59    *libkernel.a:mempool.*(.literal .text .literal.* .text.*)
60
61    *libzephyr.a:esp_loader.*(.literal .text .literal.* .text.*)
62    *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*)
63
64    *(.literal.esp_intr_disable .literal.esp_intr_disable.* .text.esp_intr_disable .text.esp_intr_disable.*)
65    *(.literal.default_intr_handler .text.default_intr_handler .iram1.*.default_intr_handler)
66    *(.literal.esp_log_timestamp .text.esp_log_timestamp)
67    *(.literal.esp_log_early_timestamp .text.esp_log_early_timestamp)
68    *(.literal.esp_system_abort .text.esp_system_abort)
69
70    *(.fini.literal)
71    *(.fini)
72    *(.gnu.version)
73    _loader_text_end = ABSOLUTE(.);
74    _iram_end = ABSOLUTE(.);
75  } > iram_loader_seg
76
77  .iram0.text :
78  {
79    /* Vectors go to IRAM */
80    _iram_start = ABSOLUTE(.);
81    _init_start = ABSOLUTE(.);
82    __text_region_start = ABSOLUTE(.);
83
84    KEEP(*(.exception_vectors.text));
85    . = ALIGN(256);
86
87    _invalid_pc_placeholder = ABSOLUTE(.);
88
89    _iram_text_start = ABSOLUTE(.);
90
91    KEEP(*(.exception.entry*)); /* contains _isr_wrapper */
92    *(.exception.other*)
93    . = ALIGN(4);
94
95    *(.entry.text)
96    *(.init.literal)
97    *(.init)
98    . = ALIGN(4);
99    *(.iram1 .iram1.*)
100    *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text)
101
102    /* C2 memprot requires 512 B alignment for split lines */
103    . = ALIGN (16);
104    _init_end = ABSOLUTE(.);
105    . = ALIGN(16);
106    *(.iram.data)
107    *(.iram.data*)
108    . = ALIGN(16);
109    *(.iram.bss)
110    *(.iram.bss*)
111
112    . = ALIGN(16);
113
114    *(.literal .text .literal.* .text.*)
115    *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
116    *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
117    *(.fini.literal)
118    *(.fini)
119    *(.gnu.version)
120
121    /* CPU will try to prefetch up to 16 bytes of
122     * of instructions. This means that any configuration (e.g. MMU, PMS) must allow
123     * safe access to up to 16 bytes after the last real instruction, add
124     * dummy bytes to ensure this
125     */
126    . += 16;
127
128    _text_end = ABSOLUTE(.);
129    __text_region_end = ABSOLUTE(.);
130    _etext = .;
131
132    /* Similar to _iram_start, this symbol goes here so it is
133     * resolved by addr2line in preference to the first symbol in
134     * the flash.text segment.
135     */
136    _flash_cache_start = ABSOLUTE(0);
137  } > iram_seg
138
139  .dram0.data :
140  {
141    . = ALIGN(4);
142    __data_start = ABSOLUTE(.);
143    *(.data)
144    *(.data.*)
145    *(.gnu.linkonce.d.*)
146    *(.data1)
147#ifdef CONFIG_RISCV_GP
148    __global_pointer$ = . + 0x800;
149#endif /* CONFIG_RISCV_GP */
150    *(.sdata)
151    *(.sdata.*)
152    *(.gnu.linkonce.s.*)
153    *(.sdata2)
154    *(.sdata2.*)
155    *(.gnu.linkonce.s2.*)
156    *libzephyr.a:mmu_hal.*(.rodata .rodata.*)
157    *libzephyr.a:rtc_clk.*(.rodata .rodata.*)
158    KEEP(*(.jcr))
159    *(.dram1 .dram1.*)
160    . = ALIGN(4);
161
162    #include <snippets-rwdata.ld>
163    . = ALIGN(4);
164
165    *(.rodata_desc .rodata_desc.*)
166    *(.rodata_custom_desc .rodata_custom_desc.*)
167
168    . = ALIGN(4);
169    #include <snippets-rodata.ld>
170    . = ALIGN(4);
171
172    *(.rodata)
173    *(.rodata.*)
174    *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
175    *(.gnu.linkonce.r.*)
176    *(.rodata1)
177    __XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
178    *(.xt_except_table)
179    *(.gcc_except_table .gcc_except_table.*)
180    *(.gnu.linkonce.e.*)
181    *(.gnu.version_r)
182    . = (. + 3) & ~ 3;
183    __eh_frame = ABSOLUTE(.);
184    KEEP(*(.eh_frame))
185    . = (. + 7) & ~ 3;
186
187    /* C++ exception handlers table: */
188    __XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
189    *(.xt_except_desc)
190    *(.gnu.linkonce.h.*)
191    __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
192    *(.xt_except_desc_end)
193    *(.dynamic)
194    *(.gnu.version_d)
195    __rodata_region_end = .;
196    _rodata_end = ABSOLUTE(.);
197    /* Literals are also RO data. */
198    _lit4_start = ABSOLUTE(.);
199    *(*.lit4)
200    *(.lit4.*)
201    *(.gnu.linkonce.lit4.*)
202    _lit4_end = ABSOLUTE(.);
203    . = ALIGN(4);
204    _thread_local_start = ABSOLUTE(.);
205    *(.tdata)
206    *(.tdata.*)
207    *(.tbss)
208    *(.tbss.*)
209    *(.srodata)
210    *(.srodata.*)
211    *(.rodata)
212    *(.rodata.*)
213    *(.rodata_wlog)
214    *(.rodata_wlog*)
215    _thread_local_end = ABSOLUTE(.);
216    /* _rodata_reserved_end = ABSOLUTE(.); */
217    . = ALIGN(4);
218  } > dram_seg
219
220  #include <zephyr/linker/common-rom/common-rom-init.ld>
221  #include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
222  #include <zephyr/linker/common-rom/common-rom-debug.ld>
223  #include <zephyr/linker/common-rom/common-rom-misc.ld>
224  #include <snippets-sections.ld>
225
226  #include <zephyr/linker/cplusplus-rom.ld>
227  #include <zephyr/linker/thread-local-storage.ld>
228  #include <snippets-data-sections.ld>
229  #include <zephyr/linker/common-ram.ld>
230  #include <snippets-ram-sections.ld>
231  #include <zephyr/linker/cplusplus-ram.ld>
232
233  #include <zephyr/linker/common-rom/common-rom-logging.ld>
234
235  .noinit (NOLOAD):
236  {
237    . = ALIGN(4);
238    *(.noinit)
239    *(.noinit.*)
240    . = ALIGN(4);
241  } > dram_seg
242
243  /* Shared RAM */
244  .bss (NOLOAD):
245  {
246    . = ALIGN (8);
247    _bss_start = ABSOLUTE(.);
248    __bss_start = ABSOLUTE(.);
249    *(.dynsbss)
250    *(.sbss)
251    *(.sbss.*)
252    *(.gnu.linkonce.sb.*)
253    *(.scommon)
254    *(.sbss2)
255    *(.sbss2.*)
256    *(.gnu.linkonce.sb2.*)
257    *(.dynbss)
258    *(.bss)
259    *(.bss.*)
260    *(.share.mem)
261    *(.gnu.linkonce.b.*)
262    *(COMMON)
263    . = ALIGN (8);
264    __bss_end = ABSOLUTE(.);
265    _bss_end = ABSOLUTE(.);
266  } > dram_seg
267
268  /* linker rel sections*/
269  #include <zephyr/linker/rel-sections.ld>
270
271#ifdef CONFIG_GEN_ISR_TABLES
272  #include <zephyr/linker/intlist.ld>
273#endif
274
275#include <zephyr/linker/debug-sections.ld>
276  /DISCARD/ : { *(.note.GNU-stack) }
277
278  SECTION_PROLOGUE(.riscv.attributes, 0,)
279    {
280    KEEP(*(.riscv.attributes))
281    KEEP(*(.gnu.attributes))
282    }
283}
284