1/*
2 * Copyright (c) 2016-2017 Jean-Paul Etienne <fractalclone@gmail.com>
3 * Copyright (c) 2021 Andes Technology Corporation
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8/**
9 * @file
10 * @brief Linker command/script file
11 *
12 * Linker script for the ae350 platform
13 */
14
15#include <soc.h>
16#include <devicetree.h>
17
18#include <autoconf.h>
19#include <linker/sections.h>
20#include <linker/devicetree_regions.h>
21
22#include <linker/linker-defs.h>
23#include <linker/linker-tool.h>
24
25#ifdef CONFIG_XIP
26#define ROMABLE_REGION              ROM
27#else
28#define ROMABLE_REGION              RAM
29#endif
30#define RAMABLE_REGION              RAM
31
32#define _VECTOR_SECTION_NAME        vector
33#define _EXCEPTION_SECTION_NAME     exceptions
34#define _RESET_SECTION_NAME         reset
35
36#ifdef CONFIG_XIP
37#if DT_NODE_HAS_COMPAT_STATUS(DT_CHOSEN(zephyr_flash), soc_nv_flash, okay)
38#ifdef CONFIG_FLASH_LOAD_OFFSET
39#define ROM_BASE (DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) + \
40				CONFIG_FLASH_LOAD_OFFSET)
41#else /* !CONFIG_FLASH_LOAD_OFFSET */
42#define ROM_BASE DT_REG_ADDR(DT_CHOSEN(zephyr_flash))
43#endif /* CONFIG_FLASH_LOAD_OFFSET */
44#define ROM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_flash))
45#elif DT_NODE_HAS_COMPAT_STATUS(DT_CHOSEN(zephyr_flash), jedec_spi_nor, okay)
46/* For jedec,spi-nor we expect the spi controller to memory map the flash
47 * and for that mapping to be the second register property of the spi
48 * controller.
49 */
50#define SPI_CTRL DT_PARENT(DT_CHOSEN(zephyr_flash))
51#define ROM_BASE DT_REG_ADDR_BY_IDX(SPI_CTRL, 1)
52#define ROM_SIZE DT_REG_SIZE_BY_IDX(SPI_CTRL, 1)
53#endif
54#else /* CONFIG_XIP */
55#define ROM_BASE CONFIG_SRAM_BASE_ADDRESS
56#define ROM_SIZE KB(CONFIG_SRAM_SIZE)
57#endif /* CONFIG_XIP */
58
59#define RAM_BASE CONFIG_SRAM_BASE_ADDRESS
60#define RAM_SIZE KB(CONFIG_SRAM_SIZE)
61
62/* Make linker section alignment comply with PMA granularity. */
63#if defined(CONFIG_SOC_ANDES_V5_PMA_REGION_MIN_ALIGN_AND_SIZE)
64_region_min_align = CONFIG_SOC_ANDES_V5_PMA_REGION_MIN_ALIGN_AND_SIZE;
65#else
66_region_min_align = 4;
67#endif
68
69#if defined(CONFIG_SOC_ANDES_V5_PMA)
70/*
71 * Andes-V5 PMA needs power-of-2 alignment.
72 */
73#define MPU_MIN_SIZE_ALIGN . = ALIGN(_region_min_align);
74#define MPU_ALIGN(region_size) \
75    . = ALIGN(_region_min_align); \
76    . = ALIGN( 1 << LOG2CEIL(region_size))
77#else
78#define MPU_MIN_SIZE_ALIGN
79#define MPU_ALIGN(region_size) \
80    . = ALIGN(_region_min_align)
81#endif
82
83MEMORY
84{
85#ifdef CONFIG_XIP
86    ROM (rx)  : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE
87#endif
88    RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE
89
90    /* Data & Instruction Tightly Coupled Memory */
91    LINKER_DT_REGION_FROM_NODE(ITCM, rw, DT_CHOSEN(zephyr_itcm))
92    LINKER_DT_REGION_FROM_NODE(DTCM, rw, DT_CHOSEN(zephyr_dtcm))
93
94    /* Used by and documented in include/linker/intlist.ld */
95    IDT_LIST  (wx)      : ORIGIN = 0xFFFFF7FF, LENGTH = 2K
96}
97
98ENTRY(CONFIG_KERNEL_ENTRY)
99
100SECTIONS
101    {
102
103#include <linker/rel-sections.ld>
104
105    /*
106     * The .plt and .iplt are here according to
107     * 'riscv32-zephyr-elf-ld --verbose', before text section.
108     */
109    SECTION_PROLOGUE(.plt,,)
110	{
111		*(.plt)
112	}
113
114    SECTION_PROLOGUE(.iplt,,)
115	{
116		*(.iplt)
117	}
118
119    GROUP_START(ROMABLE_REGION)
120    __rom_region_start = ROM_BASE;
121
122    SECTION_PROLOGUE(_VECTOR_SECTION_NAME,,)
123    {
124		/* In XIP mode, the .init section must be at the start of ROM */
125		. = ALIGN(4);
126		KEEP(*(.init.*))
127		. = ALIGN(4);
128		KEEP(*(.vectors.*))
129    } GROUP_LINK_IN(ROMABLE_REGION)
130
131    SECTION_PROLOGUE(rom_start,,)
132    {
133		. = ALIGN(16);
134/* Located in generated directory. This file is populated by calling
135 * zephyr_linker_sources(ROM_START ...).
136 */
137#include <snippets-rom-start.ld>
138    } GROUP_LINK_IN(ROMABLE_REGION)
139
140    SECTION_PROLOGUE(_RESET_SECTION_NAME,,)
141    {
142		KEEP(*(.reset.*))
143    } GROUP_LINK_IN(ROMABLE_REGION)
144
145    SECTION_PROLOGUE(_EXCEPTION_SECTION_NAME,,)
146    {
147		 KEEP(*(".exception.entry.*"))
148		 *(".exception.other.*")
149    } GROUP_LINK_IN(ROMABLE_REGION)
150
151    SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
152	{
153		. = ALIGN(4);
154		KEEP(*(.openocd_debug))
155		KEEP(*(".openocd_debug.*"))
156
157		__text_region_start = .;
158
159		*(.text)
160		*(".text.*")
161		*(.gnu.linkonce.t.*)
162#include <linker/kobject-text.ld>
163#ifdef CONFIG_SOC_FLASH_RAMCODE_SECTION
164		. = ALIGN(0x1000);
165		_ram_code_start = .;
166		KEEP(*(.__ram_code))
167		__ram_code_size = . - _ram_code_start;
168		ASSERT((__ram_code_size <= 0x1000),
169			"__ram_code_size <= 4k bytes");
170#endif
171	} GROUP_LINK_IN(ROMABLE_REGION)
172
173    __text_region_end = .;
174
175	__rodata_region_start = .;
176#include <linker/common-rom.ld>
177#include <linker/thread-local-storage.ld>
178
179    SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
180	{
181		 . = ALIGN(4);
182		 *(.srodata)
183		 *(".srodata.*")
184		 *(.rodata)
185		 *(".rodata.*")
186		 *(.gnu.linkonce.r.*)
187		 *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
188
189/* Located in generated directory. This file is populated by the
190 * zephyr_linker_sources() Cmake function.
191 */
192#include <snippets-rodata.ld>
193#include <linker/kobject-rom.ld>
194	. = ALIGN(4);
195	} GROUP_LINK_IN(ROMABLE_REGION)
196
197#include <linker/cplusplus-rom.ld>
198	__rodata_region_end = .;
199	MPU_ALIGN(__rodata_region_end - __rom_region_start);
200    GROUP_END(ROMABLE_REGION)
201
202    GROUP_START(RAMABLE_REGION)
203
204#if defined(CONFIG_USERSPACE)
205#define APP_SHARED_ALIGN MPU_MIN_SIZE_ALIGN
206#define SMEM_PARTITION_ALIGN MPU_ALIGN
207
208#include <app_smem.ld>
209
210	_image_ram_start = _app_smem_start;
211	_app_smem_size = _app_smem_end - _app_smem_start;
212	_app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
213#endif /* CONFIG_USERSPACE */
214
215    SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
216	{
217		MPU_MIN_SIZE_ALIGN
218		/*
219		 * For performance, BSS section is assumed to be 4 byte aligned and
220		 * a multiple of 4 bytes
221		 */
222		 . = ALIGN(4);
223		 __bss_start = .;
224		 _image_ram_start = .;
225		__kernel_ram_start = .;
226		 *(.sbss)
227		 *(".sbss.*")
228		 *(.bss)
229		 *(".bss.*")
230		 COMMON_SYMBOLS
231		 /*
232		  * As memory is cleared in words only, it is simpler to ensure the BSS
233		  * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
234		  */
235		  __bss_end = ALIGN(4);
236	}  GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
237
238#include <linker/common-noinit.ld>
239#include <linker/cplusplus-ram.ld>
240
241    __data_region_start = .;
242
243    SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
244	{
245		 . = ALIGN(4);
246		/* _image_ram_start = .; */
247		 __data_start = .;
248
249		 *(.data)
250		 *(".data.*")
251
252#ifdef CONFIG_RISCV_GP
253		/*
254		 * RISC-V architecture has 12-bit signed immediate offsets in the
255		 * instructions. If we can put the most commonly accessed globals
256		 * in a special 4K span of memory addressed by the GP register, then
257		 * we can access those values in a single instruction, saving both
258		 * codespace and runtime.
259		 *
260		 * Since these immediate offsets are signed, place gp 0x800 past the
261		 * beginning of .sdata so that we can use both positive and negative
262		 * offsets.
263		 */
264		 . = ALIGN(8);
265		 PROVIDE (__global_pointer$ = . + 0x800);
266#endif
267
268		 *(.sdata .sdata.* .gnu.linkonce.s.*)
269
270/* Located in generated directory. This file is populated by the
271 * zephyr_linker_sources() Cmake function.
272 */
273#include <snippets-rwdata.ld>
274		 __data_end = .;
275
276	}  GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
277	__data_size = __data_end - __data_start;
278	__data_load_start = LOADADDR(_DATA_SECTION_NAME);
279
280	__data_region_load_start = LOADADDR(_DATA_SECTION_NAME);
281
282#include <linker/common-ram.ld>
283#include <linker/kobject-data.ld>
284
285/* Located in generated directory. This file is populated by the
286 * zephyr_linker_sources() Cmake function.
287 */
288#include <snippets-ram-sections.ld>
289
290/* Located in generated directory. This file is populated by the
291 * zephyr_linker_sources() Cmake function.
292 */
293#include <snippets-data-sections.ld>
294
295    __data_region_end = .;
296
297    MPU_MIN_SIZE_ALIGN
298
299     _image_ram_end = .;
300     _end = .; /* end of image */
301
302	__kernel_ram_end = .;
303	__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
304
305#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay)
306GROUP_START(ITCM)
307
308	SECTION_PROLOGUE(_ITCM_SECTION_NAME,,SUBALIGN(8))
309	{
310		__itcm_start = .;
311		*(.itcm)
312		*(".itcm.*")
313		__itcm_end = .;
314	} GROUP_LINK_IN(ITCM AT> ROMABLE_REGION)
315
316	__itcm_size = __itcm_end - __itcm_start;
317	__itcm_rom_start = LOADADDR(_ITCM_SECTION_NAME);
318
319GROUP_END(ITCM)
320#endif
321
322#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay)
323GROUP_START(DTCM)
324
325	SECTION_PROLOGUE(_DTCM_BSS_SECTION_NAME, (NOLOAD),SUBALIGN(8))
326	{
327		__dtcm_start = .;
328		__dtcm_bss_start = .;
329		*(.dtcm_bss)
330		*(".dtcm_bss.*")
331		__dtcm_bss_end = .;
332	} GROUP_LINK_IN(DTCM)
333
334	SECTION_PROLOGUE(_DTCM_NOINIT_SECTION_NAME, (NOLOAD),SUBALIGN(8))
335	{
336		__dtcm_noinit_start = .;
337		*(.dtcm_noinit)
338		*(".dtcm_noinit.*")
339		__dtcm_noinit_end = .;
340	} GROUP_LINK_IN(DTCM)
341
342	SECTION_PROLOGUE(_DTCM_DATA_SECTION_NAME,,SUBALIGN(8))
343	{
344		__dtcm_data_start = .;
345		*(.dtcm_data)
346		*(".dtcm_data.*")
347		__dtcm_data_end = .;
348	} GROUP_LINK_IN(DTCM AT> ROMABLE_REGION)
349
350	__dtcm_end = .;
351
352	__dtcm_data_rom_start = LOADADDR(_DTCM_DATA_SECTION_NAME);
353
354GROUP_END(DTCM)
355#endif
356
357/* Located in generated directory. This file is populated by the
358 * zephyr_linker_sources() Cmake function.
359 */
360#include <snippets-sections.ld>
361
362     GROUP_END(RAMABLE_REGION)
363
364#include <linker/debug-sections.ld>
365
366    /DISCARD/ : { *(.note.GNU-stack) }
367
368    SECTION_PROLOGUE(.riscv.attributes, 0,)
369	{
370	KEEP(*(.riscv.attributes))
371	KEEP(*(.gnu.attributes))
372	}
373
374/* Must be last in romable region */
375SECTION_PROLOGUE(.last_section,(NOLOAD),)
376{
377} GROUP_LINK_IN(ROMABLE_REGION)
378
379/* To provide the image size as a const expression,
380 * calculate this value here. */
381__rom_region_end = LOADADDR(.last_section);
382__rom_region_size = __rom_region_end - __rom_region_start;
383
384}
385