• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  NOTES
150  /* Data section */
151
152  _sdata = .;
153  RW_DATA_SECTION(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE)
154  _edata = .;
155
156  /* Initialization code and data: */
157
158  . = ALIGN(PAGE_SIZE);
159  __init_begin = .;
160  INIT_TEXT_SECTION(PAGE_SIZE)
161
162  .init.data :
163  {
164    INIT_DATA
165    . = ALIGN(0x4);
166    __tagtable_begin = .;
167    *(.taglist)
168    __tagtable_end = .;
169
170    . = ALIGN(16);
171    __boot_reloc_table_start = ABSOLUTE(.);
172
173#ifdef CONFIG_VECTORS_OFFSET
174    RELOCATE_ENTRY(_WindowVectors_text,
175		   .WindowVectors.text);
176#if XCHAL_EXCM_LEVEL >= 2
177    RELOCATE_ENTRY(_Level2InterruptVector_text,
178		   .Level2InterruptVector.text);
179#endif
180#if XCHAL_EXCM_LEVEL >= 3
181    RELOCATE_ENTRY(_Level3InterruptVector_text,
182		   .Level3InterruptVector.text);
183#endif
184#if XCHAL_EXCM_LEVEL >= 4
185    RELOCATE_ENTRY(_Level4InterruptVector_text,
186		   .Level4InterruptVector.text);
187#endif
188#if XCHAL_EXCM_LEVEL >= 5
189    RELOCATE_ENTRY(_Level5InterruptVector_text,
190		   .Level5InterruptVector.text);
191#endif
192#if XCHAL_EXCM_LEVEL >= 6
193    RELOCATE_ENTRY(_Level6InterruptVector_text,
194		   .Level6InterruptVector.text);
195#endif
196    RELOCATE_ENTRY(_KernelExceptionVector_text,
197		   .KernelExceptionVector.text);
198    RELOCATE_ENTRY(_UserExceptionVector_text,
199		   .UserExceptionVector.text);
200    RELOCATE_ENTRY(_DoubleExceptionVector_literal,
201		   .DoubleExceptionVector.literal);
202    RELOCATE_ENTRY(_DoubleExceptionVector_text,
203		   .DoubleExceptionVector.text);
204    RELOCATE_ENTRY(_DebugInterruptVector_text,
205		   .DebugInterruptVector.text);
206#endif
207#if defined(CONFIG_SMP)
208    RELOCATE_ENTRY(_SecondaryResetVector_text,
209		   .SecondaryResetVector.text);
210#endif
211
212
213    __boot_reloc_table_end = ABSOLUTE(.) ;
214
215    INIT_SETUP(XCHAL_ICACHE_LINESIZE)
216    INIT_CALLS
217    CON_INITCALL
218    SECURITY_INITCALL
219    INIT_RAM_FS
220  }
221
222  PERCPU_SECTION(XCHAL_ICACHE_LINESIZE)
223
224  /* We need this dummy segment here */
225
226  . = ALIGN(4);
227  .dummy : { LONG(0) }
228
229#ifdef CONFIG_VECTORS_OFFSET
230  /* The vectors are relocated to the real position at startup time */
231
232  SECTION_VECTOR (_WindowVectors_text,
233		  .WindowVectors.text,
234		  WINDOW_VECTORS_VADDR, 4,
235		  .dummy)
236  SECTION_VECTOR (_DebugInterruptVector_literal,
237		  .DebugInterruptVector.literal,
238		  DEBUG_VECTOR_VADDR - 4,
239		  SIZEOF(.WindowVectors.text),
240		  .WindowVectors.text)
241  SECTION_VECTOR (_DebugInterruptVector_text,
242		  .DebugInterruptVector.text,
243		  DEBUG_VECTOR_VADDR,
244		  4,
245		  .DebugInterruptVector.literal)
246#undef LAST
247#define LAST	.DebugInterruptVector.text
248#if XCHAL_EXCM_LEVEL >= 2
249  SECTION_VECTOR (_Level2InterruptVector_text,
250		  .Level2InterruptVector.text,
251		  INTLEVEL2_VECTOR_VADDR,
252		  SIZEOF(LAST), LAST)
253# undef LAST
254# define LAST	.Level2InterruptVector.text
255#endif
256#if XCHAL_EXCM_LEVEL >= 3
257  SECTION_VECTOR (_Level3InterruptVector_text,
258		  .Level3InterruptVector.text,
259		  INTLEVEL3_VECTOR_VADDR,
260		  SIZEOF(LAST), LAST)
261# undef LAST
262# define LAST	.Level3InterruptVector.text
263#endif
264#if XCHAL_EXCM_LEVEL >= 4
265  SECTION_VECTOR (_Level4InterruptVector_text,
266		  .Level4InterruptVector.text,
267		  INTLEVEL4_VECTOR_VADDR,
268		  SIZEOF(LAST), LAST)
269# undef LAST
270# define LAST	.Level4InterruptVector.text
271#endif
272#if XCHAL_EXCM_LEVEL >= 5
273  SECTION_VECTOR (_Level5InterruptVector_text,
274		  .Level5InterruptVector.text,
275		  INTLEVEL5_VECTOR_VADDR,
276		  SIZEOF(LAST), LAST)
277# undef LAST
278# define LAST	.Level5InterruptVector.text
279#endif
280#if XCHAL_EXCM_LEVEL >= 6
281  SECTION_VECTOR (_Level6InterruptVector_text,
282		  .Level6InterruptVector.text,
283		  INTLEVEL6_VECTOR_VADDR,
284		  SIZEOF(LAST), LAST)
285# undef LAST
286# define LAST	.Level6InterruptVector.text
287#endif
288  SECTION_VECTOR (_KernelExceptionVector_literal,
289		  .KernelExceptionVector.literal,
290		  KERNEL_VECTOR_VADDR - 4,
291		  SIZEOF(LAST), LAST)
292#undef LAST
293  SECTION_VECTOR (_KernelExceptionVector_text,
294		  .KernelExceptionVector.text,
295		  KERNEL_VECTOR_VADDR,
296		  4,
297		  .KernelExceptionVector.literal)
298  SECTION_VECTOR (_UserExceptionVector_literal,
299		  .UserExceptionVector.literal,
300		  USER_VECTOR_VADDR - 4,
301		  SIZEOF(.KernelExceptionVector.text),
302		  .KernelExceptionVector.text)
303  SECTION_VECTOR (_UserExceptionVector_text,
304		  .UserExceptionVector.text,
305		  USER_VECTOR_VADDR,
306		  4,
307		  .UserExceptionVector.literal)
308  SECTION_VECTOR (_DoubleExceptionVector_literal,
309		  .DoubleExceptionVector.literal,
310		  DOUBLEEXC_VECTOR_VADDR - 20,
311		  SIZEOF(.UserExceptionVector.text),
312		  .UserExceptionVector.text)
313  SECTION_VECTOR (_DoubleExceptionVector_text,
314		  .DoubleExceptionVector.text,
315		  DOUBLEEXC_VECTOR_VADDR,
316		  20,
317		  .DoubleExceptionVector.literal)
318
319  . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
320
321#endif
322#if defined(CONFIG_SMP)
323
324  SECTION_VECTOR (_SecondaryResetVector_text,
325		  .SecondaryResetVector.text,
326		  RESET_VECTOR1_VADDR,
327		  SIZEOF(.DoubleExceptionVector.text),
328		  .DoubleExceptionVector.text)
329
330  . = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text);
331
332#endif
333
334  . = ALIGN(PAGE_SIZE);
335
336  __init_end = .;
337
338  BSS_SECTION(0, 8192, 0)
339
340  _end = .;
341
342  .xt.lit : { *(.xt.lit) }
343  .xt.prop : { *(.xt.prop) }
344
345  .debug  0 :  { *(.debug) }
346  .line  0 :  { *(.line) }
347  .debug_srcinfo  0 :  { *(.debug_srcinfo) }
348  .debug_sfnames  0 :  { *(.debug_sfnames) }
349  .debug_aranges  0 :  { *(.debug_aranges) }
350  .debug_pubnames  0 :  { *(.debug_pubnames) }
351  .debug_info  0 :  { *(.debug_info) }
352  .debug_abbrev  0 :  { *(.debug_abbrev) }
353  .debug_line  0 :  { *(.debug_line) }
354  .debug_frame  0 :  { *(.debug_frame) }
355  .debug_str  0 :  { *(.debug_str) }
356  .debug_loc  0 :  { *(.debug_loc) }
357  .debug_macinfo  0 :  { *(.debug_macinfo) }
358  .debug_weaknames  0 :  { *(.debug_weaknames) }
359  .debug_funcnames  0 :  { *(.debug_funcnames) }
360  .debug_typenames  0 :  { *(.debug_typenames) }
361  .debug_varnames  0 :  { *(.debug_varnames) }
362
363  .xt.insn 0 :
364  {
365    *(.xt.insn)
366    *(.gnu.linkonce.x*)
367  }
368
369  .xt.lit 0 :
370  {
371    *(.xt.lit)
372    *(.gnu.linkonce.p*)
373  }
374
375  /* Sections to be discarded */
376  DISCARDS
377  /DISCARD/ : { *(.exit.literal) }
378}
379