xref: /openbmc/linux/arch/xtensa/kernel/vmlinux.lds.S (revision 4e1a33b1)
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(__cpuidle_text_start) = .;
93    *(.cpuidle.literal .cpuidle.text)
94    VMLINUX_SYMBOL(__cpuidle_text_end) = .;
95    VMLINUX_SYMBOL(__lock_text_start) = .;
96    *(.spinlock.literal .spinlock.text)
97    VMLINUX_SYMBOL(__lock_text_end) = .;
98
99  }
100  _etext = .;
101  PROVIDE (etext = .);
102
103  . = ALIGN(16);
104
105  RODATA
106
107  /*  Relocation table */
108
109  .fixup   : { *(.fixup) }
110
111  EXCEPTION_TABLE(16)
112  /* Data section */
113
114  _sdata = .;
115  RW_DATA_SECTION(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE)
116  _edata = .;
117
118  /* Initialization code and data: */
119
120  . = ALIGN(PAGE_SIZE);
121  __init_begin = .;
122  INIT_TEXT_SECTION(PAGE_SIZE)
123
124  .init.data :
125  {
126    INIT_DATA
127    . = ALIGN(0x4);
128    __tagtable_begin = .;
129    *(.taglist)
130    __tagtable_end = .;
131
132    . = ALIGN(16);
133    __boot_reloc_table_start = ABSOLUTE(.);
134
135    RELOCATE_ENTRY(_WindowVectors_text,
136		   .WindowVectors.text);
137#if XCHAL_EXCM_LEVEL >= 2
138    RELOCATE_ENTRY(_Level2InterruptVector_text,
139		   .Level2InterruptVector.text);
140#endif
141#if XCHAL_EXCM_LEVEL >= 3
142    RELOCATE_ENTRY(_Level3InterruptVector_text,
143		   .Level3InterruptVector.text);
144#endif
145#if XCHAL_EXCM_LEVEL >= 4
146    RELOCATE_ENTRY(_Level4InterruptVector_text,
147		   .Level4InterruptVector.text);
148#endif
149#if XCHAL_EXCM_LEVEL >= 5
150    RELOCATE_ENTRY(_Level5InterruptVector_text,
151		   .Level5InterruptVector.text);
152#endif
153#if XCHAL_EXCM_LEVEL >= 6
154    RELOCATE_ENTRY(_Level6InterruptVector_text,
155		   .Level6InterruptVector.text);
156#endif
157    RELOCATE_ENTRY(_KernelExceptionVector_text,
158		   .KernelExceptionVector.text);
159    RELOCATE_ENTRY(_UserExceptionVector_text,
160		   .UserExceptionVector.text);
161    RELOCATE_ENTRY(_DoubleExceptionVector_literal,
162		   .DoubleExceptionVector.literal);
163    RELOCATE_ENTRY(_DoubleExceptionVector_text,
164		   .DoubleExceptionVector.text);
165    RELOCATE_ENTRY(_DebugInterruptVector_text,
166		   .DebugInterruptVector.text);
167#if defined(CONFIG_SMP)
168    RELOCATE_ENTRY(_SecondaryResetVector_text,
169		   .SecondaryResetVector.text);
170#endif
171
172
173    __boot_reloc_table_end = ABSOLUTE(.) ;
174
175    INIT_SETUP(XCHAL_ICACHE_LINESIZE)
176    INIT_CALLS
177    CON_INITCALL
178    SECURITY_INITCALL
179    INIT_RAM_FS
180  }
181
182  PERCPU_SECTION(XCHAL_ICACHE_LINESIZE)
183
184  /* We need this dummy segment here */
185
186  . = ALIGN(4);
187  .dummy : { LONG(0) }
188
189  /* The vectors are relocated to the real position at startup time */
190
191  SECTION_VECTOR (_WindowVectors_text,
192		  .WindowVectors.text,
193		  WINDOW_VECTORS_VADDR, 4,
194		  .dummy)
195  SECTION_VECTOR (_DebugInterruptVector_literal,
196		  .DebugInterruptVector.literal,
197		  DEBUG_VECTOR_VADDR - 4,
198		  SIZEOF(.WindowVectors.text),
199		  .WindowVectors.text)
200  SECTION_VECTOR (_DebugInterruptVector_text,
201		  .DebugInterruptVector.text,
202		  DEBUG_VECTOR_VADDR,
203		  4,
204		  .DebugInterruptVector.literal)
205#undef LAST
206#define LAST	.DebugInterruptVector.text
207#if XCHAL_EXCM_LEVEL >= 2
208  SECTION_VECTOR (_Level2InterruptVector_text,
209		  .Level2InterruptVector.text,
210		  INTLEVEL2_VECTOR_VADDR,
211		  SIZEOF(LAST), LAST)
212# undef LAST
213# define LAST	.Level2InterruptVector.text
214#endif
215#if XCHAL_EXCM_LEVEL >= 3
216  SECTION_VECTOR (_Level3InterruptVector_text,
217		  .Level3InterruptVector.text,
218		  INTLEVEL3_VECTOR_VADDR,
219		  SIZEOF(LAST), LAST)
220# undef LAST
221# define LAST	.Level3InterruptVector.text
222#endif
223#if XCHAL_EXCM_LEVEL >= 4
224  SECTION_VECTOR (_Level4InterruptVector_text,
225		  .Level4InterruptVector.text,
226		  INTLEVEL4_VECTOR_VADDR,
227		  SIZEOF(LAST), LAST)
228# undef LAST
229# define LAST	.Level4InterruptVector.text
230#endif
231#if XCHAL_EXCM_LEVEL >= 5
232  SECTION_VECTOR (_Level5InterruptVector_text,
233		  .Level5InterruptVector.text,
234		  INTLEVEL5_VECTOR_VADDR,
235		  SIZEOF(LAST), LAST)
236# undef LAST
237# define LAST	.Level5InterruptVector.text
238#endif
239#if XCHAL_EXCM_LEVEL >= 6
240  SECTION_VECTOR (_Level6InterruptVector_text,
241		  .Level6InterruptVector.text,
242		  INTLEVEL6_VECTOR_VADDR,
243		  SIZEOF(LAST), LAST)
244# undef LAST
245# define LAST	.Level6InterruptVector.text
246#endif
247  SECTION_VECTOR (_KernelExceptionVector_literal,
248		  .KernelExceptionVector.literal,
249		  KERNEL_VECTOR_VADDR - 4,
250		  SIZEOF(LAST), LAST)
251#undef LAST
252  SECTION_VECTOR (_KernelExceptionVector_text,
253		  .KernelExceptionVector.text,
254		  KERNEL_VECTOR_VADDR,
255		  4,
256		  .KernelExceptionVector.literal)
257  SECTION_VECTOR (_UserExceptionVector_literal,
258		  .UserExceptionVector.literal,
259		  USER_VECTOR_VADDR - 4,
260		  SIZEOF(.KernelExceptionVector.text),
261		  .KernelExceptionVector.text)
262  SECTION_VECTOR (_UserExceptionVector_text,
263		  .UserExceptionVector.text,
264		  USER_VECTOR_VADDR,
265		  4,
266		  .UserExceptionVector.literal)
267  SECTION_VECTOR (_DoubleExceptionVector_literal,
268		  .DoubleExceptionVector.literal,
269		  DOUBLEEXC_VECTOR_VADDR - 48,
270		  SIZEOF(.UserExceptionVector.text),
271		  .UserExceptionVector.text)
272  SECTION_VECTOR (_DoubleExceptionVector_text,
273		  .DoubleExceptionVector.text,
274		  DOUBLEEXC_VECTOR_VADDR,
275		  48,
276		  .DoubleExceptionVector.literal)
277
278  . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
279
280#if defined(CONFIG_SMP)
281
282  SECTION_VECTOR (_SecondaryResetVector_text,
283		  .SecondaryResetVector.text,
284		  RESET_VECTOR1_VADDR,
285		  SIZEOF(.DoubleExceptionVector.text),
286		  .DoubleExceptionVector.text)
287
288  . = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text);
289
290#endif
291
292  . = ALIGN(PAGE_SIZE);
293
294  __init_end = .;
295
296  BSS_SECTION(0, 8192, 0)
297
298  _end = .;
299
300  .xt.lit : { *(.xt.lit) }
301  .xt.prop : { *(.xt.prop) }
302
303  .debug  0 :  { *(.debug) }
304  .line  0 :  { *(.line) }
305  .debug_srcinfo  0 :  { *(.debug_srcinfo) }
306  .debug_sfnames  0 :  { *(.debug_sfnames) }
307  .debug_aranges  0 :  { *(.debug_aranges) }
308  .debug_pubnames  0 :  { *(.debug_pubnames) }
309  .debug_info  0 :  { *(.debug_info) }
310  .debug_abbrev  0 :  { *(.debug_abbrev) }
311  .debug_line  0 :  { *(.debug_line) }
312  .debug_frame  0 :  { *(.debug_frame) }
313  .debug_str  0 :  { *(.debug_str) }
314  .debug_loc  0 :  { *(.debug_loc) }
315  .debug_macinfo  0 :  { *(.debug_macinfo) }
316  .debug_weaknames  0 :  { *(.debug_weaknames) }
317  .debug_funcnames  0 :  { *(.debug_funcnames) }
318  .debug_typenames  0 :  { *(.debug_typenames) }
319  .debug_varnames  0 :  { *(.debug_varnames) }
320
321  .xt.insn 0 :
322  {
323    *(.xt.insn)
324    *(.gnu.linkonce.x*)
325  }
326
327  .xt.lit 0 :
328  {
329    *(.xt.lit)
330    *(.gnu.linkonce.p*)
331  }
332
333  /* Sections to be discarded */
334  DISCARDS
335  /DISCARD/ : { *(.exit.literal) }
336}
337