1/*
2 * Copyright (c) 2013-2014 Wind River Systems, Inc.
3 * Copyright (c) 2016-2017 Jean-Paul Etienne <fractalclone@gmail.com>
4 * Copyright (c) 2018 Foundries.io Ltd
5 * Copyright (c) 2024 sensry.io
6 *
7 * This file is based on:
8 *
9 * - include/arch/arm/cortex_m/scripts/linker.ld
10 * - include/arch/riscv/common/linker.ld
11 * - include/arch/riscv/pulpino/linker.ld
12 *
13 * SPDX-License-Identifier: Apache-2.0
14 */
15
16#include <zephyr/devicetree.h>
17
18#include <zephyr/linker/sections.h>
19#include <zephyr/linker/linker-defs.h>
20#include <zephyr/linker/linker-tool.h>
21
22#define MPU_ALIGN(region_size) . = ALIGN(4)
23
24/*
25 * Extra efforts would need to be taken to ensure the IRQ handlers are within
26 * jumping distance of the vector table in non-XIP builds, so avoid them.
27 */
28#define ROMABLE_REGION              ROM
29#define RAMABLE_REGION              RAM
30
31## ROM AREA ##
32#define ROM_BASE        0x1C010100
33#define ROM_SIZE        0x5Fa00
34
35## RAM AREA ##
36#define RAM_BASE        0x1C070000
37#define RAM_SIZE        0x200000
38
39MEMORY
40    {
41        L2_START  (rx)          : ORIGIN = 0x1c010000, LENGTH = 0x00000080
42        L2_VALIDITY (rx)        : ORIGIN = 0x1c010080, LENGTH = 0x00000080
43
44        ROM (rx)                : ORIGIN = ROM_BASE,    LENGTH = ROM_SIZE       /*  392kb */
45        RAM (rwx)               : ORIGIN = RAM_BASE,    LENGTH = RAM_SIZE       /* 2097kb */
46
47        L2_PRIV_CH0             : ORIGIN = 0x1c004100, LENGTH = 0x2000          /* uDMA access */
48
49        /*
50         * Special section, not included in the final binary, used
51         * to generate interrupt tables. See include/linker/intlist.ld.
52         */
53        IDT_LIST                : ORIGIN = 0xFFFFF7FF, LENGTH = 2K
54    }
55
56ENTRY(CONFIG_KERNEL_ENTRY)
57
58SECTIONS
59    {
60
61        .pre_start MAX(0x1c010000,ALIGN(0x80)) :
62        {
63            KEEP(*(.pre_start))
64        } > L2_START
65
66        .validity_marker MAX(0x1c010080,ALIGN(0x80)) :
67        {
68            KEEP(*(.validity_marker))
69        } > L2_VALIDITY
70
71        /* uninitialized space for uDMA access */
72        .udma_access (NOLOAD): {
73            . = ALIGN(4);
74            _udma_space_start = .;
75            *(.udma_access)
76            _udma_space_end = .;
77        } > L2_PRIV_CH0
78
79        #include <zephyr/linker/rel-sections.ld>
80
81        #ifdef CONFIG_LLEXT
82        #include <zephyr/linker/llext-sections.ld>
83        #endif
84
85        SECTION_PROLOGUE(.plt,,)
86        {
87            *(.plt)
88        }
89
90
91        SECTION_PROLOGUE(.iplt,,)
92        {
93            *(.iplt)
94        }
95
96
97        GROUP_START(ROM)
98        __rom_region_start = ROM_BASE;
99
100            SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
101            {
102
103                /* Located in generated directory. This file is populated by calling
104                 * zephyr_linker_sources(ROM_START ...). This typically contains the vector
105                 * table and debug information.
106                 */
107                #include <snippets-rom-start.ld>
108
109                __text_region_start = .;
110
111                *(.text .text.*)
112                *(.gnu.linkonce.t.*)
113                *(.eh_frame)
114
115            } GROUP_LINK_IN(ROM)
116
117            __text_region_end = .;
118
119
120            __rodata_region_start = .;
121
122                #include <zephyr/linker/common-rom.ld>
123                #include <zephyr/linker/thread-local-storage.ld>
124
125                SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
126                {
127                    . = ALIGN(4);
128                    *(.srodata)
129                    *(".srodata.*")
130                    *(.rodata)
131                    *(.rodata.*)
132                    *(.gnu.linkonce.r.*)
133
134                    /* Located in generated directory. This file is populated by the
135                     * zephyr_linker_sources() Cmake function.
136                     */
137                    #include <snippets-rodata.ld>
138
139                } GROUP_LINK_IN(ROMABLE_REGION)
140
141                #include <zephyr/linker/cplusplus-rom.ld>
142
143            __rodata_region_end = .;
144
145    __rom_region_end = .;
146    GROUP_END(ROM)
147
148    GROUP_START(RAM)
149
150        SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
151        {
152        . = ALIGN(4);
153        _image_ram_start = .;
154        __data_region_start = .;
155        __data_start = .;
156
157        *(.data)
158        *(.data.*)
159        *(.gnu.linkonce.s.*)
160
161        /* https://groups.google.com/a/groups.riscv.org/d/msg/sw-dev/60IdaZj27dY/TKT3hbNlAgAJ */
162        *(.sdata .sdata.* .gnu.linkonce.s.*)
163        *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
164
165        /* Located in generated directory. This file is populated by the
166         * zephyr_linker_sources() Cmake function.
167         */
168        #include <snippets-rwdata.ld>
169
170	    __data_end = .;
171
172        } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
173	    __data_size = __data_end - __data_start;
174
175
176	    __data_load_start = LOADADDR(_DATA_SECTION_NAME);
177
178            #include <zephyr/linker/common-ram.ld>
179            #include <zephyr/linker/cplusplus-ram.ld>
180
181            /* Located in generated directory. This file is populated by the
182             * zephyr_linker_sources() Cmake function.
183             */
184            #include <snippets-data-sections.ld>
185
186        __data_region_end = .;
187        __data_region_load_start = LOADADDR(_DATA_SECTION_NAME);
188
189        SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
190        {
191        /*
192         * For performance, BSS section is assumed to be 4 byte aligned and
193         * a multiple of 4 bytes, so it can be cleared in words.
194         */
195         . = ALIGN(4);
196         __bss_start = .;
197
198         *(.bss .bss.*)
199         *(.sbss .sbss.*)
200         COMMON_SYMBOLS
201
202         /* Ensure 4 byte alignment for the entire section. */
203         . = ALIGN(4);
204          __bss_end = .;
205        } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
206
207        SECTION_PROLOGUE(_NOINIT_SECTION_NAME,(NOLOAD),)
208        {
209        /*
210         * This section is used for non-initialized objects that
211         * will not be cleared during the boot process.
212         */
213         *(.noinit .noinit.*)
214
215        /* Located in generated directory. This file is populated by the
216         * zephyr_linker_sources() Cmake function.
217         */
218        #include <snippets-noinit.ld>
219
220        } GROUP_LINK_IN(RAMABLE_REGION)
221
222        /* Located in generated directory. This file is populated by the
223         * zephyr_linker_sources() Cmake function.
224         */
225        #include <snippets-ram-sections.ld>
226
227        /* Located in generated directory. This file is populated by the
228         * zephyr_linker_sources() Cmake function.
229         */
230        #include <snippets-sections.ld>
231
232        #include <zephyr/linker/ram-end.ld>
233
234        GROUP_END(RAMABLE_REGION)
235
236        #ifdef CONFIG_GEN_ISR_TABLES
237        /* Bogus section, post-processed during the build to initialize interrupts. */
238        #include <zephyr/linker/intlist.ld>
239        #endif
240
241        #include <zephyr/linker/debug-sections.ld>
242
243        SECTION_PROLOGUE(.riscv.attributes, 0,)
244        {
245            KEEP(*(.riscv.attributes))
246            KEEP(*(.gnu.attributes))
247        }
248
249        /*
250         * Pulpino toolchains emit these sections; we don't care about them,
251         * but need to avoid build system warnings about orphaned sections.
252         */
253        SECTION_PROLOGUE(.Pulp_Chip.Info,,)
254        {
255            *(.Pulp_Chip.*)
256        }
257
258    }
259