xref: /linux/arch/xtensa/kernel/vmlinux.lds.S (revision 1d87200446f1d10dfe9672ca8edb027a82612f8c)
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#define RO_EXCEPTION_TABLE_ALIGN	16
18
19#include <asm-generic/vmlinux.lds.h>
20#include <asm/page.h>
21#include <asm/thread_info.h>
22
23#include <asm/core.h>
24#include <asm/vectors.h>
25
26OUTPUT_ARCH(xtensa)
27ENTRY(_start)
28
29#ifdef __XTENSA_EB__
30jiffies = jiffies_64 + 4;
31#else
32jiffies = jiffies_64;
33#endif
34
35/* Note: In the following macros, it would be nice to specify only the
36   vector name and section kind and construct "sym" and "section" using
37   CPP concatenation, but that does not work reliably.  Concatenating a
38   string with "." produces an invalid token.  CPP will not print a
39   warning because it thinks this is an assembly file, but it leaves
40   them as multiple tokens and there may or may not be whitespace
41   between them.  */
42
43/* Macro for a relocation entry */
44
45#define RELOCATE_ENTRY(sym, section)		\
46	LONG(sym ## _start);			\
47	LONG(sym ## _end);			\
48	LONG(LOADADDR(section))
49
50/*
51 * Macro to define a section for a vector. When CONFIG_VECTORS_OFFSET is
52 * defined code for every vector is located with other init data. At startup
53 * time head.S copies code for every vector to its final position according
54 * to description recorded in the corresponding RELOCATE_ENTRY.
55 */
56
57#ifdef CONFIG_VECTORS_OFFSET
58#define SECTION_VECTOR(sym, section, addr, prevsec)                         \
59  section addr : AT(((LOADADDR(prevsec) + SIZEOF(prevsec)) + 3) & ~ 3)      \
60  {									    \
61    . = ALIGN(4);							    \
62    sym ## _start = ABSOLUTE(.);		 			    \
63    *(section)								    \
64    sym ## _end = ABSOLUTE(.);						    \
65  }
66#else
67#define SECTION_VECTOR(section, addr)					    \
68  . = addr;								    \
69  *(section)
70#endif
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
89#ifndef CONFIG_VECTORS_OFFSET
90  . = ALIGN(PAGE_SIZE);
91  _vecbase = .;
92
93  SECTION_VECTOR (.WindowVectors.text, WINDOW_VECTORS_VADDR)
94#if XCHAL_EXCM_LEVEL >= 2
95  SECTION_VECTOR (.Level2InterruptVector.text, INTLEVEL2_VECTOR_VADDR)
96#endif
97#if XCHAL_EXCM_LEVEL >= 3
98  SECTION_VECTOR (.Level3InterruptVector.text, INTLEVEL3_VECTOR_VADDR)
99#endif
100#if XCHAL_EXCM_LEVEL >= 4
101  SECTION_VECTOR (.Level4InterruptVector.text, INTLEVEL4_VECTOR_VADDR)
102#endif
103#if XCHAL_EXCM_LEVEL >= 5
104  SECTION_VECTOR (.Level5InterruptVector.text, INTLEVEL5_VECTOR_VADDR)
105#endif
106#if XCHAL_EXCM_LEVEL >= 6
107  SECTION_VECTOR (.Level6InterruptVector.text, INTLEVEL6_VECTOR_VADDR)
108#endif
109  SECTION_VECTOR (.DebugInterruptVector.text, DEBUG_VECTOR_VADDR)
110  SECTION_VECTOR (.KernelExceptionVector.text, KERNEL_VECTOR_VADDR)
111  SECTION_VECTOR (.UserExceptionVector.text, USER_VECTOR_VADDR)
112  SECTION_VECTOR (.DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR)
113#endif
114
115    IRQENTRY_TEXT
116    SOFTIRQENTRY_TEXT
117    ENTRY_TEXT
118    TEXT_TEXT
119    SCHED_TEXT
120    CPUIDLE_TEXT
121    LOCK_TEXT
122
123  }
124  _etext = .;
125  PROVIDE (etext = .);
126
127  . = ALIGN(16);
128
129  RO_DATA(4096)
130
131  /*  Relocation table */
132
133  .fixup   : { *(.fixup) }
134
135  /* Data section */
136
137  _sdata = .;
138  RW_DATA(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE)
139  _edata = .;
140
141  /* Initialization code and data: */
142
143  . = ALIGN(PAGE_SIZE);
144  __init_begin = .;
145  INIT_TEXT_SECTION(PAGE_SIZE)
146
147  .init.data :
148  {
149    INIT_DATA
150    . = ALIGN(0x4);
151    __tagtable_begin = .;
152    *(.taglist)
153    __tagtable_end = .;
154
155    . = ALIGN(16);
156    __boot_reloc_table_start = ABSOLUTE(.);
157
158#ifdef CONFIG_VECTORS_OFFSET
159    RELOCATE_ENTRY(_WindowVectors_text,
160		   .WindowVectors.text);
161#if XCHAL_EXCM_LEVEL >= 2
162    RELOCATE_ENTRY(_Level2InterruptVector_text,
163		   .Level2InterruptVector.text);
164#endif
165#if XCHAL_EXCM_LEVEL >= 3
166    RELOCATE_ENTRY(_Level3InterruptVector_text,
167		   .Level3InterruptVector.text);
168#endif
169#if XCHAL_EXCM_LEVEL >= 4
170    RELOCATE_ENTRY(_Level4InterruptVector_text,
171		   .Level4InterruptVector.text);
172#endif
173#if XCHAL_EXCM_LEVEL >= 5
174    RELOCATE_ENTRY(_Level5InterruptVector_text,
175		   .Level5InterruptVector.text);
176#endif
177#if XCHAL_EXCM_LEVEL >= 6
178    RELOCATE_ENTRY(_Level6InterruptVector_text,
179		   .Level6InterruptVector.text);
180#endif
181    RELOCATE_ENTRY(_KernelExceptionVector_text,
182		   .KernelExceptionVector.text);
183    RELOCATE_ENTRY(_UserExceptionVector_text,
184		   .UserExceptionVector.text);
185    RELOCATE_ENTRY(_DoubleExceptionVector_text,
186		   .DoubleExceptionVector.text);
187    RELOCATE_ENTRY(_DebugInterruptVector_text,
188		   .DebugInterruptVector.text);
189#endif
190#if defined(CONFIG_SMP)
191    RELOCATE_ENTRY(_SecondaryResetVector_text,
192		   .SecondaryResetVector.text);
193#endif
194
195
196    __boot_reloc_table_end = ABSOLUTE(.) ;
197
198    INIT_SETUP(XCHAL_ICACHE_LINESIZE)
199    INIT_CALLS
200    CON_INITCALL
201    INIT_RAM_FS
202  }
203
204  PERCPU_SECTION(XCHAL_ICACHE_LINESIZE)
205
206  /* We need this dummy segment here */
207
208  . = ALIGN(4);
209  .dummy : { LONG(0) }
210
211#ifdef CONFIG_VECTORS_OFFSET
212  /* The vectors are relocated to the real position at startup time */
213
214  SECTION_VECTOR (_WindowVectors_text,
215		  .WindowVectors.text,
216		  WINDOW_VECTORS_VADDR,
217		  .dummy)
218  SECTION_VECTOR (_DebugInterruptVector_text,
219		  .DebugInterruptVector.text,
220		  DEBUG_VECTOR_VADDR,
221		  .WindowVectors.text)
222#undef LAST
223#define LAST	.DebugInterruptVector.text
224#if XCHAL_EXCM_LEVEL >= 2
225  SECTION_VECTOR (_Level2InterruptVector_text,
226		  .Level2InterruptVector.text,
227		  INTLEVEL2_VECTOR_VADDR,
228		  LAST)
229# undef LAST
230# define LAST	.Level2InterruptVector.text
231#endif
232#if XCHAL_EXCM_LEVEL >= 3
233  SECTION_VECTOR (_Level3InterruptVector_text,
234		  .Level3InterruptVector.text,
235		  INTLEVEL3_VECTOR_VADDR,
236		  LAST)
237# undef LAST
238# define LAST	.Level3InterruptVector.text
239#endif
240#if XCHAL_EXCM_LEVEL >= 4
241  SECTION_VECTOR (_Level4InterruptVector_text,
242		  .Level4InterruptVector.text,
243		  INTLEVEL4_VECTOR_VADDR,
244		  LAST)
245# undef LAST
246# define LAST	.Level4InterruptVector.text
247#endif
248#if XCHAL_EXCM_LEVEL >= 5
249  SECTION_VECTOR (_Level5InterruptVector_text,
250		  .Level5InterruptVector.text,
251		  INTLEVEL5_VECTOR_VADDR,
252		  LAST)
253# undef LAST
254# define LAST	.Level5InterruptVector.text
255#endif
256#if XCHAL_EXCM_LEVEL >= 6
257  SECTION_VECTOR (_Level6InterruptVector_text,
258		  .Level6InterruptVector.text,
259		  INTLEVEL6_VECTOR_VADDR,
260		  LAST)
261# undef LAST
262# define LAST	.Level6InterruptVector.text
263#endif
264  SECTION_VECTOR (_KernelExceptionVector_text,
265		  .KernelExceptionVector.text,
266		  KERNEL_VECTOR_VADDR,
267		  LAST)
268#undef LAST
269  SECTION_VECTOR (_UserExceptionVector_text,
270		  .UserExceptionVector.text,
271		  USER_VECTOR_VADDR,
272		  .KernelExceptionVector.text)
273  SECTION_VECTOR (_DoubleExceptionVector_text,
274		  .DoubleExceptionVector.text,
275		  DOUBLEEXC_VECTOR_VADDR,
276		  .UserExceptionVector.text)
277
278  . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
279
280#endif
281#if defined(CONFIG_SMP)
282
283  SECTION_VECTOR (_SecondaryResetVector_text,
284		  .SecondaryResetVector.text,
285		  RESET_VECTOR1_VADDR,
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  DWARF_DEBUG
301
302  .xt.prop 0 : { KEEP(*(.xt.prop .xt.prop.* .gnu.linkonce.prop.*)) }
303  .xt.insn 0 : { KEEP(*(.xt.insn .xt.insn.* .gnu.linkonce.x*)) }
304  .xt.lit  0 : { KEEP(*(.xt.lit  .xt.lit.*  .gnu.linkonce.p*)) }
305
306  /* Sections to be discarded */
307  DISCARDS
308}
309