xref: /openbmc/linux/arch/xtensa/kernel/vmlinux.lds.S (revision 23c2b932)
1/*
2 * arch/xtensa/kernel/vmlinux.lds.S
3 *
4 * Xtensa linker script
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License.  See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2008 Tensilica Inc.
11 *
12 * Chris Zankel <chris@zankel.net>
13 * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
14 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
15 */
16
17#include <asm-generic/vmlinux.lds.h>
18#include <asm/page.h>
19#include <asm/thread_info.h>
20
21#include <asm/vectors.h>
22#include <variant/core.h>
23#include <platform/hardware.h>
24OUTPUT_ARCH(xtensa)
25ENTRY(_start)
26
27#ifdef __XTENSA_EB__
28jiffies = jiffies_64 + 4;
29#else
30jiffies = jiffies_64;
31#endif
32
33/* Note: In the following macros, it would be nice to specify only the
34   vector name and section kind and construct "sym" and "section" using
35   CPP concatenation, but that does not work reliably.  Concatenating a
36   string with "." produces an invalid token.  CPP will not print a
37   warning because it thinks this is an assembly file, but it leaves
38   them as multiple tokens and there may or may not be whitespace
39   between them.  */
40
41/* Macro for a relocation entry */
42
43#define RELOCATE_ENTRY(sym, section)		\
44	LONG(sym ## _start);			\
45	LONG(sym ## _end);			\
46	LONG(LOADADDR(section))
47
48/* Macro to define a section for a vector.
49 *
50 * Use of the MIN function catches the types of errors illustrated in
51 * the following example:
52 *
53 * Assume the section .DoubleExceptionVector.literal is completely
54 * full.  Then a programmer adds code to .DoubleExceptionVector.text
55 * that produces another literal.  The final literal position will
56 * overlay onto the first word of the adjacent code section
57 * .DoubleExceptionVector.text.  (In practice, the literals will
58 * overwrite the code, and the first few instructions will be
59 * garbage.)
60 */
61
62#define SECTION_VECTOR(sym, section, addr, max_prevsec_size, prevsec)       \
63  section addr : AT((MIN(LOADADDR(prevsec) + max_prevsec_size,		    \
64		         LOADADDR(prevsec) + SIZEOF(prevsec)) + 3) & ~ 3)   \
65  {									    \
66    . = ALIGN(4);							    \
67    sym ## _start = ABSOLUTE(.);		 			    \
68    *(section)								    \
69    sym ## _end = ABSOLUTE(.);						    \
70  }
71
72/*
73 *  Mapping of input sections to output sections when linking.
74 */
75
76SECTIONS
77{
78  . = KERNELOFFSET;
79  /* .text section */
80
81  _text = .;
82  _stext = .;
83
84  .text :
85  {
86    /* The HEAD_TEXT section must be the first section! */
87    HEAD_TEXT
88    TEXT_TEXT
89    VMLINUX_SYMBOL(__sched_text_start) = .;
90    *(.sched.literal .sched.text)
91    VMLINUX_SYMBOL(__sched_text_end) = .;
92    VMLINUX_SYMBOL(__lock_text_start) = .;
93    *(.spinlock.literal .spinlock.text)
94    VMLINUX_SYMBOL(__lock_text_end) = .;
95
96  }
97  _etext = .;
98  PROVIDE (etext = .);
99
100  . = ALIGN(16);
101
102  RODATA
103
104  /*  Relocation table */
105
106  .fixup   : { *(.fixup) }
107
108  EXCEPTION_TABLE(16)
109  /* Data section */
110
111  _sdata = .;
112  RW_DATA_SECTION(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE)
113  _edata = .;
114
115  /* Initialization code and data: */
116
117  . = ALIGN(PAGE_SIZE);
118  __init_begin = .;
119  INIT_TEXT_SECTION(PAGE_SIZE)
120
121  .init.data :
122  {
123    INIT_DATA
124    . = ALIGN(0x4);
125    __tagtable_begin = .;
126    *(.taglist)
127    __tagtable_end = .;
128
129    . = ALIGN(16);
130    __boot_reloc_table_start = ABSOLUTE(.);
131
132    RELOCATE_ENTRY(_WindowVectors_text,
133		   .WindowVectors.text);
134#if XCHAL_EXCM_LEVEL >= 2
135    RELOCATE_ENTRY(_Level2InterruptVector_text,
136		   .Level2InterruptVector.text);
137#endif
138#if XCHAL_EXCM_LEVEL >= 3
139    RELOCATE_ENTRY(_Level3InterruptVector_text,
140		   .Level3InterruptVector.text);
141#endif
142#if XCHAL_EXCM_LEVEL >= 4
143    RELOCATE_ENTRY(_Level4InterruptVector_text,
144		   .Level4InterruptVector.text);
145#endif
146#if XCHAL_EXCM_LEVEL >= 5
147    RELOCATE_ENTRY(_Level5InterruptVector_text,
148		   .Level5InterruptVector.text);
149#endif
150#if XCHAL_EXCM_LEVEL >= 6
151    RELOCATE_ENTRY(_Level6InterruptVector_text,
152		   .Level6InterruptVector.text);
153#endif
154    RELOCATE_ENTRY(_KernelExceptionVector_text,
155		   .KernelExceptionVector.text);
156    RELOCATE_ENTRY(_UserExceptionVector_text,
157		   .UserExceptionVector.text);
158    RELOCATE_ENTRY(_DoubleExceptionVector_literal,
159		   .DoubleExceptionVector.literal);
160    RELOCATE_ENTRY(_DoubleExceptionVector_text,
161		   .DoubleExceptionVector.text);
162    RELOCATE_ENTRY(_DebugInterruptVector_text,
163		   .DebugInterruptVector.text);
164#if defined(CONFIG_SMP)
165    RELOCATE_ENTRY(_SecondaryResetVector_text,
166		   .SecondaryResetVector.text);
167#endif
168
169
170    __boot_reloc_table_end = ABSOLUTE(.) ;
171
172    INIT_SETUP(XCHAL_ICACHE_LINESIZE)
173    INIT_CALLS
174    CON_INITCALL
175    SECURITY_INITCALL
176    INIT_RAM_FS
177  }
178
179  PERCPU_SECTION(XCHAL_ICACHE_LINESIZE)
180
181  /* We need this dummy segment here */
182
183  . = ALIGN(4);
184  .dummy : { LONG(0) }
185
186  /* The vectors are relocated to the real position at startup time */
187
188  SECTION_VECTOR (_WindowVectors_text,
189		  .WindowVectors.text,
190		  WINDOW_VECTORS_VADDR, 4,
191		  .dummy)
192  SECTION_VECTOR (_DebugInterruptVector_literal,
193		  .DebugInterruptVector.literal,
194		  DEBUG_VECTOR_VADDR - 4,
195		  SIZEOF(.WindowVectors.text),
196		  .WindowVectors.text)
197  SECTION_VECTOR (_DebugInterruptVector_text,
198		  .DebugInterruptVector.text,
199		  DEBUG_VECTOR_VADDR,
200		  4,
201		  .DebugInterruptVector.literal)
202#undef LAST
203#define LAST	.DebugInterruptVector.text
204#if XCHAL_EXCM_LEVEL >= 2
205  SECTION_VECTOR (_Level2InterruptVector_text,
206		  .Level2InterruptVector.text,
207		  INTLEVEL2_VECTOR_VADDR,
208		  SIZEOF(LAST), LAST)
209# undef LAST
210# define LAST	.Level2InterruptVector.text
211#endif
212#if XCHAL_EXCM_LEVEL >= 3
213  SECTION_VECTOR (_Level3InterruptVector_text,
214		  .Level3InterruptVector.text,
215		  INTLEVEL3_VECTOR_VADDR,
216		  SIZEOF(LAST), LAST)
217# undef LAST
218# define LAST	.Level3InterruptVector.text
219#endif
220#if XCHAL_EXCM_LEVEL >= 4
221  SECTION_VECTOR (_Level4InterruptVector_text,
222		  .Level4InterruptVector.text,
223		  INTLEVEL4_VECTOR_VADDR,
224		  SIZEOF(LAST), LAST)
225# undef LAST
226# define LAST	.Level4InterruptVector.text
227#endif
228#if XCHAL_EXCM_LEVEL >= 5
229  SECTION_VECTOR (_Level5InterruptVector_text,
230		  .Level5InterruptVector.text,
231		  INTLEVEL5_VECTOR_VADDR,
232		  SIZEOF(LAST), LAST)
233# undef LAST
234# define LAST	.Level5InterruptVector.text
235#endif
236#if XCHAL_EXCM_LEVEL >= 6
237  SECTION_VECTOR (_Level6InterruptVector_text,
238		  .Level6InterruptVector.text,
239		  INTLEVEL6_VECTOR_VADDR,
240		  SIZEOF(LAST), LAST)
241# undef LAST
242# define LAST	.Level6InterruptVector.text
243#endif
244  SECTION_VECTOR (_KernelExceptionVector_literal,
245		  .KernelExceptionVector.literal,
246		  KERNEL_VECTOR_VADDR - 4,
247		  SIZEOF(LAST), LAST)
248#undef LAST
249  SECTION_VECTOR (_KernelExceptionVector_text,
250		  .KernelExceptionVector.text,
251		  KERNEL_VECTOR_VADDR,
252		  4,
253		  .KernelExceptionVector.literal)
254  SECTION_VECTOR (_UserExceptionVector_literal,
255		  .UserExceptionVector.literal,
256		  USER_VECTOR_VADDR - 4,
257		  SIZEOF(.KernelExceptionVector.text),
258		  .KernelExceptionVector.text)
259  SECTION_VECTOR (_UserExceptionVector_text,
260		  .UserExceptionVector.text,
261		  USER_VECTOR_VADDR,
262		  4,
263		  .UserExceptionVector.literal)
264  SECTION_VECTOR (_DoubleExceptionVector_literal,
265		  .DoubleExceptionVector.literal,
266		  DOUBLEEXC_VECTOR_VADDR - 48,
267		  SIZEOF(.UserExceptionVector.text),
268		  .UserExceptionVector.text)
269  SECTION_VECTOR (_DoubleExceptionVector_text,
270		  .DoubleExceptionVector.text,
271		  DOUBLEEXC_VECTOR_VADDR,
272		  48,
273		  .DoubleExceptionVector.literal)
274
275  . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
276
277#if defined(CONFIG_SMP)
278
279  SECTION_VECTOR (_SecondaryResetVector_text,
280		  .SecondaryResetVector.text,
281		  RESET_VECTOR1_VADDR,
282		  SIZEOF(.DoubleExceptionVector.text),
283		  .DoubleExceptionVector.text)
284
285  . = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text);
286
287#endif
288
289  . = ALIGN(PAGE_SIZE);
290
291  __init_end = .;
292
293  BSS_SECTION(0, 8192, 0)
294
295  _end = .;
296
297  .xt.lit : { *(.xt.lit) }
298  .xt.prop : { *(.xt.prop) }
299
300  .debug  0 :  { *(.debug) }
301  .line  0 :  { *(.line) }
302  .debug_srcinfo  0 :  { *(.debug_srcinfo) }
303  .debug_sfnames  0 :  { *(.debug_sfnames) }
304  .debug_aranges  0 :  { *(.debug_aranges) }
305  .debug_pubnames  0 :  { *(.debug_pubnames) }
306  .debug_info  0 :  { *(.debug_info) }
307  .debug_abbrev  0 :  { *(.debug_abbrev) }
308  .debug_line  0 :  { *(.debug_line) }
309  .debug_frame  0 :  { *(.debug_frame) }
310  .debug_str  0 :  { *(.debug_str) }
311  .debug_loc  0 :  { *(.debug_loc) }
312  .debug_macinfo  0 :  { *(.debug_macinfo) }
313  .debug_weaknames  0 :  { *(.debug_weaknames) }
314  .debug_funcnames  0 :  { *(.debug_funcnames) }
315  .debug_typenames  0 :  { *(.debug_typenames) }
316  .debug_varnames  0 :  { *(.debug_varnames) }
317
318  .xt.insn 0 :
319  {
320    *(.xt.insn)
321    *(.gnu.linkonce.x*)
322  }
323
324  .xt.lit 0 :
325  {
326    *(.xt.lit)
327    *(.gnu.linkonce.p*)
328  }
329
330  /* Sections to be discarded */
331  DISCARDS
332  /DISCARD/ : { *(.exit.literal) }
333}
334