1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (c) 2004-2008 Texas Instruments
4 *
5 * (C) Copyright 2002
6 * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
7 */
8
9#include <config.h>
10#include <asm/psci.h>
11
12OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
13OUTPUT_ARCH(arm)
14ENTRY(_start)
15SECTIONS
16{
17#if defined(CONFIG_ARMV7_SECURE_BASE) && defined(CONFIG_ARMV7_NONSEC)
18	/*
19	 * If CONFIG_ARMV7_SECURE_BASE is true, secure code will not
20	 * bundle with u-boot, and code offsets are fixed. Secure zone
21	 * only needs to be copied from the loading address to
22	 * CONFIG_ARMV7_SECURE_BASE, which is the linking and running
23	 * address for secure code.
24	 *
25	 * If CONFIG_ARMV7_SECURE_BASE is undefined, the secure zone will
26	 * be included in u-boot address space, and some absolute address
27	 * were used in secure code. The absolute addresses of the secure
28	 * code also needs to be relocated along with the accompanying u-boot
29	 * code.
30	 *
31	 * So DISCARD is only for CONFIG_ARMV7_SECURE_BASE.
32	 */
33	/DISCARD/ : { *(.rel._secure*) }
34#endif
35	. = 0x00000000;
36
37	. = ALIGN(4);
38	__image_copy_start = ADDR(.text);
39	.text :
40	{
41		*(.vectors)
42		CPUDIR/start.o (.text*)
43	}
44
45	/* This needs to come before *(.text*) */
46	.efi_runtime : {
47		__efi_runtime_start = .;
48		*(.text.efi_runtime*)
49		*(.rodata.efi_runtime*)
50		*(.data.efi_runtime*)
51		__efi_runtime_stop = .;
52	}
53
54	.text_rest :
55	{
56		*(.text*)
57	}
58
59#ifdef CONFIG_ARMV7_NONSEC
60
61	/* Align the secure section only if we're going to use it in situ */
62	.__secure_start
63#ifndef CONFIG_ARMV7_SECURE_BASE
64		ALIGN(CONSTANT(COMMONPAGESIZE))
65#endif
66	: {
67		KEEP(*(.__secure_start))
68	}
69
70#ifndef CONFIG_ARMV7_SECURE_BASE
71#define __ARMV7_SECURE_BASE
72#define __ARMV7_PSCI_STACK_IN_RAM
73#else
74#define __ARMV7_SECURE_BASE	CONFIG_ARMV7_SECURE_BASE
75#endif
76
77	.secure_text __ARMV7_SECURE_BASE :
78		AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
79	{
80		*(._secure.text)
81	}
82
83	.secure_data : AT(LOADADDR(.secure_text) + SIZEOF(.secure_text))
84	{
85		*(._secure.data)
86	}
87
88#ifdef CONFIG_ARMV7_PSCI
89	.secure_stack ALIGN(ADDR(.secure_data) + SIZEOF(.secure_data),
90			    CONSTANT(COMMONPAGESIZE)) (NOLOAD) :
91#ifdef __ARMV7_PSCI_STACK_IN_RAM
92		AT(ADDR(.secure_stack))
93#else
94		AT(LOADADDR(.secure_data) + SIZEOF(.secure_data))
95#endif
96	{
97		KEEP(*(.__secure_stack_start))
98
99		/* Skip addreses for stack */
100		. = . + CONFIG_ARMV7_PSCI_NR_CPUS * ARM_PSCI_STACK_SIZE;
101
102		/* Align end of stack section to page boundary */
103		. = ALIGN(CONSTANT(COMMONPAGESIZE));
104
105		KEEP(*(.__secure_stack_end))
106
107#ifdef CONFIG_ARMV7_SECURE_MAX_SIZE
108		/*
109		 * We are not checking (__secure_end - __secure_start) here,
110		 * as these are the load addresses, and do not include the
111		 * stack section. Instead, use the end of the stack section
112		 * and the start of the text section.
113		 */
114		ASSERT((. - ADDR(.secure_text)) <= CONFIG_ARMV7_SECURE_MAX_SIZE,
115		       "Error: secure section exceeds secure memory size");
116#endif
117	}
118
119#ifndef __ARMV7_PSCI_STACK_IN_RAM
120	/* Reset VMA but don't allocate space if we have secure SRAM */
121	. = LOADADDR(.secure_stack);
122#endif
123
124#endif
125
126	.__secure_end : AT(ADDR(.__secure_end)) {
127		*(.__secure_end)
128		LONG(0x1d1071c);	/* Must output something to reset LMA */
129	}
130#endif
131
132	. = ALIGN(4);
133	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
134
135	. = ALIGN(4);
136	.data : {
137		*(.data*)
138	}
139
140	. = ALIGN(4);
141
142	. = .;
143
144	. = ALIGN(4);
145	__u_boot_list : {
146		KEEP(*(SORT(__u_boot_list*)));
147	}
148
149	.efi_runtime_rel : {
150		__efi_runtime_rel_start = .;
151		*(.rel*.efi_runtime)
152		*(.rel*.efi_runtime.*)
153		__efi_runtime_rel_stop = .;
154	}
155
156	. = ALIGN(8);
157	__image_copy_end = .;
158
159	/*
160	 * if CONFIG_USE_ARCH_MEMSET is not selected __bss_end - __bss_start
161	 * needs to be a multiple of 8 and we overlay .bss with .rel.dyn
162	 */
163	.rel.dyn ALIGN(8) : {
164		__rel_dyn_start = .;
165		*(.rel*)
166		__rel_dyn_end = .;
167	}
168
169	_end = .;
170	_image_binary_end = .;
171
172/*
173 * These sections occupy the same memory, but their lifetimes do
174 * not overlap: U-Boot initializes .bss only after applying dynamic
175 * relocations and therefore after it doesn't need .rel.dyn any more.
176 */
177	.bss ADDR(.rel.dyn) (OVERLAY): {
178		__bss_start = .;
179		*(.bss*)
180		. = ALIGN(4);
181		__bss_end = .;
182	}
183
184	/DISCARD/ : { *(.dynsym) }
185	/DISCARD/ : { *(.dynbss) }
186	/DISCARD/ : { *(.dynstr*) }
187	/DISCARD/ : { *(.dynamic*) }
188	/DISCARD/ : { *(.plt*) }
189	/DISCARD/ : { *(.interp*) }
190	/DISCARD/ : { *(.gnu.hash) }
191	/DISCARD/ : { *(.gnu*) }
192	/DISCARD/ : { *(.ARM.exidx*) }
193	/DISCARD/ : { *(.gnu.linkonce.armexidx.*) }
194}
195