1/*
2 * Copyright (c) 2020 ITE Corporation. All Rights Reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#include <soc.h>
8#include <zephyr/devicetree.h>
9
10#include <zephyr/linker/sections.h>
11#include <zephyr/linker/devicetree_regions.h>
12
13#include <zephyr/linker/linker-defs.h>
14#include <zephyr/linker/linker-tool.h>
15
16#ifdef CONFIG_XIP
17#define ROMABLE_REGION              ROM
18#else
19#define ROMABLE_REGION              RAM
20#endif
21#define RAMABLE_REGION              RAM
22
23#define _EXCEPTION_SECTION_NAME     exceptions
24#define _RESET_SECTION_NAME         reset
25
26#ifdef CONFIG_XIP
27#if DT_NODE_HAS_COMPAT_STATUS(DT_CHOSEN(zephyr_flash), soc_nv_flash, okay)
28#ifdef CONFIG_FLASH_LOAD_OFFSET
29#define ROM_BASE (DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) + \
30				CONFIG_FLASH_LOAD_OFFSET)
31#else /* !CONFIG_FLASH_LOAD_OFFSET */
32#define ROM_BASE DT_REG_ADDR(DT_CHOSEN(zephyr_flash))
33#endif /* CONFIG_FLASH_LOAD_OFFSET */
34#define ROM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_flash))
35#elif DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_flash), jedec_spi_nor)
36/* For jedec,spi-nor we expect the spi controller to memory map the flash
37 * and for that mapping to be the second register property of the spi
38 * controller.
39 */
40#define SPI_CTRL DT_PARENT(DT_CHOSEN(zephyr_flash))
41#define ROM_BASE DT_REG_ADDR_BY_IDX(SPI_CTRL, 1)
42#define ROM_SIZE DT_REG_SIZE_BY_IDX(SPI_CTRL, 1)
43#endif
44#else /* CONFIG_XIP */
45#define ROM_BASE CONFIG_SRAM_BASE_ADDRESS
46#define ROM_SIZE KB(CONFIG_SRAM_SIZE)
47#endif /* CONFIG_XIP */
48
49#define RAM_BASE CONFIG_SRAM_BASE_ADDRESS
50#define RAM_SIZE KB(CONFIG_SRAM_SIZE)
51
52#ifdef CONFIG_RISCV_PMP
53	#define MPU_MIN_SIZE 4
54	#define MPU_MIN_SIZE_ALIGN . = ALIGN(MPU_MIN_SIZE);
55	#if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
56		#define MPU_ALIGN(region_size) \
57			. = ALIGN(MPU_MIN_SIZE); \
58			. = ALIGN( 1 << LOG2CEIL(region_size))
59	#else
60		#define MPU_ALIGN(region_size) \
61			. = ALIGN(MPU_MIN_SIZE)
62	#endif
63#else
64	#define MPU_MIN_SIZE_ALIGN
65	#define MPU_ALIGN(region_size) . = ALIGN(4)
66#endif
67
68#include <zephyr/linker/linker-devnull.h>
69
70MEMORY
71{
72#ifdef CONFIG_XIP
73    ROM (rx)  : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE
74#endif
75    RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE
76
77#if defined(CONFIG_LINKER_DEVNULL_MEMORY)
78    DEVNULL_ROM (rx) : ORIGIN = DEVNULL_ADDR, LENGTH = DEVNULL_SIZE
79#endif
80
81    LINKER_DT_REGIONS()
82
83    /* Used by and documented in include/linker/intlist.ld */
84    IDT_LIST  (wx)      : ORIGIN = 0xFFFFF7FF, LENGTH = 2K
85}
86
87ENTRY(CONFIG_KERNEL_ENTRY)
88
89SECTIONS
90    {
91
92#include <zephyr/linker/rel-sections.ld>
93
94#ifdef CONFIG_LLEXT
95#include <zephyr/linker/llext-sections.ld>
96#endif
97
98    /*
99     * The .plt and .iplt are here according to
100     * 'riscv32-zephyr-elf-ld --verbose', before text section.
101     */
102    SECTION_PROLOGUE(.plt,,)
103	{
104		*(.plt)
105	}
106
107    SECTION_PROLOGUE(.iplt,,)
108	{
109		*(.iplt)
110	}
111
112    GROUP_START(ROMABLE_REGION)
113    __rom_region_start = ROM_BASE;
114
115    SECTION_PROLOGUE(rom_start,,)
116    {
117		. = ALIGN(16);
118/* Located in generated directory. This file is populated by calling
119 * zephyr_linker_sources(ROM_START ...).
120 */
121#include <snippets-rom-start.ld>
122    } GROUP_LINK_IN(ROMABLE_REGION)
123
124#ifdef CONFIG_CODE_DATA_RELOCATION
125#include <linker_relocate.ld>
126#endif
127
128    SECTION_PROLOGUE(_RESET_SECTION_NAME,,)
129    {
130		KEEP(*(.reset.*))
131    } GROUP_LINK_IN(ROMABLE_REGION)
132
133#ifdef CONFIG_SOC_IT8XXX2_JTAG_DEBUG_INTERFACE
134#define JTAG_DEBUG_RESERVED_ADDR_START 0x80000800
135#define JTAG_DEBUG_RESERVED_ADDR_END 0x800008FF
136	/* The CPU address from 0x80000800 to 0x800008FF is reserved for JTAG
137	 * debug usage. */
138	SECTION_PROLOGUE(jtag_dbg,,)
139	{
140		__jtag_dbg_pad_start = ABSOLUTE(.);
141		ASSERT((__jtag_dbg_pad_start < JTAG_DEBUG_RESERVED_ADDR_START),
142			"The start address of jtag debug section is incorrect.");
143
144		__jtag_dbg_pad_size = JTAG_DEBUG_RESERVED_ADDR_END - __jtag_dbg_pad_start;
145		. = . + __jtag_dbg_pad_size;
146
147		__jtag_dbg_pad_end = ABSOLUTE(.);
148		ASSERT((__jtag_dbg_pad_end == JTAG_DEBUG_RESERVED_ADDR_END),
149			"The end address of jtag debug section is incorrect.");
150	} GROUP_LINK_IN(ROMABLE_REGION)
151#endif
152
153#ifndef CONFIG_SOC_IT8XXX2_EXCEPTIONS_IN_RAM
154    SECTION_PROLOGUE(_EXCEPTION_SECTION_NAME,,)
155	{
156		KEEP(*(".exception.entry.*"))
157		*(".exception.other.*")
158	} GROUP_LINK_IN(ROMABLE_REGION)
159#endif
160
161    SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
162	{
163		. = ALIGN(4);
164		KEEP(*(.openocd_debug))
165		KEEP(*(".openocd_debug.*"))
166
167		__text_region_start = .;
168#ifndef CONFIG_SOC_IT8XXX2_LIBRARY_TO_RAM
169		*(.text)
170		*(".text.*")
171#endif
172
173#ifdef CONFIG_SOC_IT8XXX2_LIBRARY_TO_RAM
174		*(EXCLUDE_FILE (
175#endif
176#ifdef CONFIG_SOC_IT8XXX2_SERIAL_IN_RAM
177			*libdrivers__serial.a:*
178#endif
179#ifdef CONFIG_SOC_IT8XXX2_KERNEL_IN_RAM
180			*libkernel.a:*
181#endif
182#ifdef CONFIG_SOC_IT8XXX2_ZEPHYR_IN_RAM
183			*libzephyr.a:*
184#endif
185#ifdef CONFIG_SOC_IT8XXX2_LIBRARY_TO_RAM
186		)
187			.text
188		)
189#endif
190
191#ifdef CONFIG_SOC_IT8XXX2_LIBRARY_TO_RAM
192		*(EXCLUDE_FILE (
193#endif
194#ifdef CONFIG_SOC_IT8XXX2_SERIAL_IN_RAM
195			*libdrivers__serial.a:*
196#endif
197#ifdef CONFIG_SOC_IT8XXX2_KERNEL_IN_RAM
198			*libkernel.a:*
199#endif
200#ifdef CONFIG_SOC_IT8XXX2_ZEPHYR_IN_RAM
201			*libzephyr.a:*
202#endif
203#ifdef CONFIG_SOC_IT8XXX2_LIBRARY_TO_RAM
204		)
205			.text.*
206		)
207#endif
208		*(.gnu.linkonce.t.*)
209#include <zephyr/linker/kobject-text.ld>
210
211		/* IT8xxx2 requires memory mappings be configured for execution
212		 * out of RAM, which refer to contiguous blocks of RAM. Place
213		 * all relevant sections together to minimize RAM waste. */
214		. = ALIGN(0x1000);
215		/* Mapping base address must be 4k-aligned */
216		__ilm_flash_start = .;
217#ifdef CONFIG_SOC_IT8XXX2_SHA256_HW_ACCELERATE
218		/* Pad to match allocation of block in RAM,
219		 * maintaining code alignment against ILM */
220		__sha256_pad_block_start = .;
221		. = . + CONFIG_SOC_IT8XXX2_SHA256_BLOCK_SIZE;
222#endif
223		/* Specially-tagged functions in SoC sources */
224		KEEP(*(.__ram_code))
225		*(.__ram_code.*)
226#ifdef CONFIG_SOC_IT8XXX2_EXCEPTIONS_IN_RAM
227		KEEP(*(".exception.entry.*"))
228		*(".exception.other.*")
229#endif
230#ifdef CONFIG_SOC_IT8XXX2_SERIAL_IN_RAM
231		*libdrivers__serial.a:*(.text .text.*)
232		*libdrivers__serial.a:*(.rodata .rodata.*)
233		*libdrivers__serial.a:*(.srodata .srodata.*)
234#endif
235#ifdef CONFIG_SOC_IT8XXX2_KERNEL_IN_RAM
236		*libkernel.a:*(.text .text.*)
237		*libkernel.a:*(.rodata .rodata.*)
238		*libkernel.a:*(.srodata .srodata.*)
239#endif
240#ifdef CONFIG_SOC_IT8XXX2_ZEPHYR_IN_RAM
241		*libzephyr.a:*(.text .text.*)
242		*libzephyr.a:*(.rodata .rodata.*)
243		*libzephyr.a:*(.srodata .srodata.*)
244#endif
245		__ilm_flash_end = .;
246		/* ILM mapping is always a multiple of 4k size; ensure following
247		 * sections won't incorrectly redirect to RAM. */
248		. = ALIGN(0x1000);
249
250	} GROUP_LINK_IN(ROMABLE_REGION)
251
252    __text_region_end = .;
253
254	__rodata_region_start = .;
255#include <zephyr/linker/common-rom.ld>
256/* Located in generated directory. This file is populated by calling
257 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs.
258 */
259#include <snippets-rom-sections.ld>
260#include <zephyr/linker/thread-local-storage.ld>
261
262    SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
263	{
264		 . = ALIGN(4);
265		 *(.srodata)
266		 *(".srodata.*")
267		 *(.rodata)
268		 *(".rodata.*")
269		 *(.gnu.linkonce.r.*)
270		 *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
271
272/* Located in generated directory. This file is populated by the
273 * zephyr_linker_sources() Cmake function.
274 */
275#include <snippets-rodata.ld>
276#include <zephyr/linker/kobject-rom.ld>
277	. = ALIGN(4);
278	} GROUP_LINK_IN(ROMABLE_REGION)
279
280#include <zephyr/linker/cplusplus-rom.ld>
281	__rodata_region_end = .;
282
283	/* For non-XIP system, __rom_region_end symbol should be set to
284	 * the end of common ROMABLE_REGIONs (text and rodata) instead of
285	 * the linker script end, so it wouldn't mistakenly contain
286	 * RAMABLE_REGION in it.
287	 */
288#ifndef CONFIG_XIP
289#ifdef CONFIG_RISCV_PMP
290	SECTION_PROLOGUE(rom_mpu_padding,,)
291	{
292		MPU_ALIGN(__rodata_region_end - __rom_region_start);
293#ifdef CONFIG_QEMU_TARGET
294		/*
295		 * QEMU doesn't vet each instruction fetch individually.
296		 * Instead, it grabs a whole page and perform dynamic
297		 * transation on it in a batch. It therefore validates
298		 * PMP permissions using page-sized and -aligned chunks.
299		 */
300		. = ALIGN(0x1000);
301#endif
302	} GROUP_LINK_IN(ROMABLE_REGION)
303#endif /* CONFIG_RISCV_PMP */
304
305	__rom_region_end = .;
306	__rom_region_size = __rom_region_end - __rom_region_start;
307#endif /* CONFIG_XIP */
308    GROUP_END(ROMABLE_REGION)
309
310    GROUP_START(RAMABLE_REGION)
311
312	. = RAM_BASE;
313
314    /* Claim RAM for ILM mappings; must be 4k-aligned and each mapping is 4k in
315     * size, but mapped regions can still be accessed as data so don't need to be
316     * padded out to 4k size. This doesn't load any sections because code in ILM
317     * is still accessed at its VMA in ROM. */
318    SECTION_PROLOGUE(ilm_ram,(NOLOAD),ALIGN(0x1000))
319	{
320		__ilm_ram_start = .;
321
322#ifdef CONFIG_SOC_IT8XXX2_SHA256_HW_ACCELERATE
323		__sha256_ram_block_start = .;
324		KEEP(*(.__sha256_ram_block))
325		__sha256_ram_block_size = \
326			ABSOLUTE(. - __sha256_ram_block_start);
327		__sha256_ram_block_end = .;
328
329		ASSERT((__sha256_ram_block_size == CONFIG_SOC_IT8XXX2_SHA256_BLOCK_SIZE), \
330			"Not compatible ram size for HW sha256 module");
331		ASSERT((__sha256_ram_block_end < (RAM_BASE + 0x1000)), \
332			"sha256 ram block must in SRAM first 4kbytes");
333		ASSERT(((ABSOLUTE(__sha256_ram_block_start) & 0xfff) == \
334			(ABSOLUTE(__sha256_pad_block_start) & 0xfff)), \
335			"sha256 ram block needs the same offset with sha256 rom block");
336#else
337		__sha256_ram_block_size = 0;
338#endif
339		. += __ilm_flash_end - __ilm_flash_start - __sha256_ram_block_size;
340		__ilm_ram_end = .;
341	} GROUP_LINK_IN(RAMABLE_REGION)
342
343	_image_ram_start = .;
344/* Located in generated directory. This file is populated by the
345 * zephyr_linker_sources() Cmake function.
346 */
347#include <snippets-ram-sections.ld>
348
349#if defined(CONFIG_USERSPACE)
350#define APP_SHARED_ALIGN MPU_MIN_SIZE_ALIGN
351#define SMEM_PARTITION_ALIGN MPU_ALIGN
352
353#include <app_smem.ld>
354
355	_app_smem_size = _app_smem_end - _app_smem_start;
356	_app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
357#endif /* CONFIG_USERSPACE */
358
359    SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
360	{
361		MPU_MIN_SIZE_ALIGN
362		/*
363		 * For performance, BSS section is assumed to be 4 byte aligned and
364		 * a multiple of 4 bytes
365		 */
366		 . = ALIGN(4);
367		 __bss_start = .;
368		__kernel_ram_start = .;
369		 *(.sbss)
370		 *(".sbss.*")
371		 *(.bss)
372		 *(".bss.*")
373		 COMMON_SYMBOLS
374
375#ifdef CONFIG_CODE_DATA_RELOCATION
376#include <linker_sram_bss_relocate.ld>
377#endif
378
379		 /*
380		  * As memory is cleared in words only, it is simpler to ensure the BSS
381		  * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
382		  */
383		  __bss_end = ALIGN(4);
384	}  GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
385
386#include <zephyr/linker/common-noinit.ld>
387
388    SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
389	{
390		 . = ALIGN(4);
391		/* _image_ram_start = .; */
392		 __data_region_start = .;
393		 __data_start = .;
394
395		 *(.data)
396		 *(".data.*")
397
398#ifdef CONFIG_RISCV_GP
399		/*
400		 * RISC-V architecture has 12-bit signed immediate offsets in the
401		 * instructions. If we can put the most commonly accessed globals
402		 * in a special 4K span of memory addressed by the GP register, then
403		 * we can access those values in a single instruction, saving both
404		 * codespace and runtime.
405		 *
406		 * Since these immediate offsets are signed, place gp 0x800 past the
407		 * beginning of .sdata so that we can use both positive and negative
408		 * offsets.
409		 */
410		 . = ALIGN(8);
411		 PROVIDE (__global_pointer$ = . + 0x800);
412#endif
413
414		 *(.sdata .sdata.* .gnu.linkonce.s.*)
415
416/* Located in generated directory. This file is populated by the
417 * zephyr_linker_sources() Cmake function.
418 */
419#include <snippets-rwdata.ld>
420
421#ifdef CONFIG_CODE_DATA_RELOCATION
422#include <linker_sram_data_relocate.ld>
423#endif
424
425		 __data_end = .;
426
427	}  GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
428	__data_size = __data_end - __data_start;
429	__data_load_start = LOADADDR(_DATA_SECTION_NAME);
430
431	__data_region_load_start = LOADADDR(_DATA_SECTION_NAME);
432
433#include <zephyr/linker/common-ram.ld>
434#include <zephyr/linker/kobject-data.ld>
435#include <zephyr/linker/cplusplus-ram.ld>
436
437/* Located in generated directory. This file is populated by the
438 * zephyr_linker_sources() Cmake function.
439 */
440#include <snippets-data-sections.ld>
441
442    __data_region_end = .;
443
444	SECTION_DATA_PROLOGUE(.h2ram_pool,(NOLOAD),)
445	{
446		/*
447		 * Since __sha256_ram_block section must in the first 4KB,
448		 * h2ram_pool section is no longer included first inside the
449		 * RAMABLE_REGION.
450		 * Append h2ram_pool section at the end of used memory, so gap
451		 * due to alignment is still available for newly added variables
452		 */
453		. = ALIGN(0x1000);
454		_h2ram_pool_start = .;
455		KEEP(*(.h2ram_pool))
456		_h2ram_pool_end = .;
457	}  GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
458	_h2ram_pool_size = ABSOLUTE(_h2ram_pool_end - _h2ram_pool_start);
459
460	__kernel_ram_end = .;
461	__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
462
463/* Located in generated directory. This file is populated by the
464 * zephyr_linker_sources() Cmake function.
465 */
466#include <snippets-sections.ld>
467
468#define LAST_RAM_ALIGN MPU_MIN_SIZE_ALIGN
469
470#include <zephyr/linker/ram-end.ld>
471
472    GROUP_END(RAMABLE_REGION)
473
474#include <zephyr/linker/debug-sections.ld>
475
476    /DISCARD/ : { *(.note.GNU-stack) }
477
478    SECTION_PROLOGUE(.riscv.attributes, 0,)
479	{
480	KEEP(*(.riscv.attributes))
481	KEEP(*(.gnu.attributes))
482	}
483
484    /* Sections generated from 'zephyr,memory-region' nodes */
485    LINKER_DT_SECTIONS()
486
487/* Because ROMABLE_REGION != RAMABLE_REGION in XIP-system, it is valid
488 * to set __rom_region_end symbol at the end of linker script and
489 * doesn't mistakenly contain the RAMABLE_REGION in it.
490 */
491#ifdef CONFIG_XIP
492/* Must be last in romable region */
493SECTION_PROLOGUE(.last_section,(NOLOAD),)
494{
495} GROUP_LINK_IN(ROMABLE_REGION)
496
497/* To provide the image size as a const expression,
498 * calculate this value here. */
499__rom_region_end = LOADADDR(.last_section);
500__rom_region_size = __rom_region_end - __rom_region_start;
501#endif
502
503}
504