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