]> asedeno.scripts.mit.edu Git - linux.git/blob - arch/xtensa/kernel/vmlinux.lds.S
37a3205c404c8c0b7525200e988f4537d51992ba
[linux.git] / arch / xtensa / kernel / vmlinux.lds.S
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
26 OUTPUT_ARCH(xtensa)
27 ENTRY(_start)
28
29 #ifdef __XTENSA_EB__
30 jiffies = jiffies_64 + 4;
31 #else
32 jiffies = 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
76 SECTIONS
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
114   *(.exception.text)
115 #endif
116
117     IRQENTRY_TEXT
118     SOFTIRQENTRY_TEXT
119     ENTRY_TEXT
120     TEXT_TEXT
121     SCHED_TEXT
122     CPUIDLE_TEXT
123     LOCK_TEXT
124     *(.fixup)
125   }
126   _etext = .;
127   PROVIDE (etext = .);
128
129   . = ALIGN(16);
130
131   RO_DATA(4096)
132
133   /* Data section */
134
135 #ifdef CONFIG_XIP_KERNEL
136   INIT_TEXT_SECTION(PAGE_SIZE)
137 #else
138   _sdata = .;
139   RW_DATA(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE)
140   _edata = .;
141
142   /* Initialization code and data: */
143
144   . = ALIGN(PAGE_SIZE);
145   __init_begin = .;
146   INIT_TEXT_SECTION(PAGE_SIZE)
147
148   .init.data :
149   {
150     INIT_DATA
151   }
152 #endif
153
154   .init.rodata :
155   {
156     . = ALIGN(0x4);
157     __tagtable_begin = .;
158     *(.taglist)
159     __tagtable_end = .;
160
161     . = ALIGN(16);
162     __boot_reloc_table_start = ABSOLUTE(.);
163
164 #ifdef CONFIG_VECTORS_OFFSET
165     RELOCATE_ENTRY(_WindowVectors_text,
166                    .WindowVectors.text);
167 #if XCHAL_EXCM_LEVEL >= 2
168     RELOCATE_ENTRY(_Level2InterruptVector_text,
169                    .Level2InterruptVector.text);
170 #endif
171 #if XCHAL_EXCM_LEVEL >= 3
172     RELOCATE_ENTRY(_Level3InterruptVector_text,
173                    .Level3InterruptVector.text);
174 #endif
175 #if XCHAL_EXCM_LEVEL >= 4
176     RELOCATE_ENTRY(_Level4InterruptVector_text,
177                    .Level4InterruptVector.text);
178 #endif
179 #if XCHAL_EXCM_LEVEL >= 5
180     RELOCATE_ENTRY(_Level5InterruptVector_text,
181                    .Level5InterruptVector.text);
182 #endif
183 #if XCHAL_EXCM_LEVEL >= 6
184     RELOCATE_ENTRY(_Level6InterruptVector_text,
185                    .Level6InterruptVector.text);
186 #endif
187     RELOCATE_ENTRY(_KernelExceptionVector_text,
188                    .KernelExceptionVector.text);
189     RELOCATE_ENTRY(_UserExceptionVector_text,
190                    .UserExceptionVector.text);
191     RELOCATE_ENTRY(_DoubleExceptionVector_text,
192                    .DoubleExceptionVector.text);
193     RELOCATE_ENTRY(_DebugInterruptVector_text,
194                    .DebugInterruptVector.text);
195     RELOCATE_ENTRY(_exception_text,
196                    .exception.text);
197 #endif
198 #ifdef CONFIG_XIP_KERNEL
199     RELOCATE_ENTRY(_xip_data, .data);
200     RELOCATE_ENTRY(_xip_init_data, .init.data);
201 #else
202 #if defined(CONFIG_SMP)
203     RELOCATE_ENTRY(_SecondaryResetVector_text,
204                    .SecondaryResetVector.text);
205 #endif
206 #endif
207
208     __boot_reloc_table_end = ABSOLUTE(.) ;
209
210     INIT_SETUP(XCHAL_ICACHE_LINESIZE)
211     INIT_CALLS
212     CON_INITCALL
213     INIT_RAM_FS
214   }
215
216   PERCPU_SECTION(XCHAL_ICACHE_LINESIZE)
217
218   /* We need this dummy segment here */
219
220   . = ALIGN(4);
221   .dummy : { LONG(0) }
222
223 #ifdef CONFIG_VECTORS_OFFSET
224   /* The vectors are relocated to the real position at startup time */
225
226   SECTION_VECTOR (_WindowVectors_text,
227                   .WindowVectors.text,
228                   WINDOW_VECTORS_VADDR,
229                   .dummy)
230   SECTION_VECTOR (_DebugInterruptVector_text,
231                   .DebugInterruptVector.text,
232                   DEBUG_VECTOR_VADDR,
233                   .WindowVectors.text)
234 #undef LAST
235 #define LAST    .DebugInterruptVector.text
236 #if XCHAL_EXCM_LEVEL >= 2
237   SECTION_VECTOR (_Level2InterruptVector_text,
238                   .Level2InterruptVector.text,
239                   INTLEVEL2_VECTOR_VADDR,
240                   LAST)
241 # undef LAST
242 # define LAST   .Level2InterruptVector.text
243 #endif
244 #if XCHAL_EXCM_LEVEL >= 3
245   SECTION_VECTOR (_Level3InterruptVector_text,
246                   .Level3InterruptVector.text,
247                   INTLEVEL3_VECTOR_VADDR,
248                   LAST)
249 # undef LAST
250 # define LAST   .Level3InterruptVector.text
251 #endif
252 #if XCHAL_EXCM_LEVEL >= 4
253   SECTION_VECTOR (_Level4InterruptVector_text,
254                   .Level4InterruptVector.text,
255                   INTLEVEL4_VECTOR_VADDR,
256                   LAST)
257 # undef LAST
258 # define LAST   .Level4InterruptVector.text
259 #endif
260 #if XCHAL_EXCM_LEVEL >= 5
261   SECTION_VECTOR (_Level5InterruptVector_text,
262                   .Level5InterruptVector.text,
263                   INTLEVEL5_VECTOR_VADDR,
264                   LAST)
265 # undef LAST
266 # define LAST   .Level5InterruptVector.text
267 #endif
268 #if XCHAL_EXCM_LEVEL >= 6
269   SECTION_VECTOR (_Level6InterruptVector_text,
270                   .Level6InterruptVector.text,
271                   INTLEVEL6_VECTOR_VADDR,
272                   LAST)
273 # undef LAST
274 # define LAST   .Level6InterruptVector.text
275 #endif
276   SECTION_VECTOR (_KernelExceptionVector_text,
277                   .KernelExceptionVector.text,
278                   KERNEL_VECTOR_VADDR,
279                   LAST)
280 #undef LAST
281   SECTION_VECTOR (_UserExceptionVector_text,
282                   .UserExceptionVector.text,
283                   USER_VECTOR_VADDR,
284                   .KernelExceptionVector.text)
285   SECTION_VECTOR (_DoubleExceptionVector_text,
286                   .DoubleExceptionVector.text,
287                   DOUBLEEXC_VECTOR_VADDR,
288                   .UserExceptionVector.text)
289 #define LAST .DoubleExceptionVector.text
290
291 #endif
292 #if !defined(CONFIG_XIP_KERNEL) && defined(CONFIG_SMP)
293
294   SECTION_VECTOR (_SecondaryResetVector_text,
295                   .SecondaryResetVector.text,
296                   RESET_VECTOR1_VADDR,
297                   .DoubleExceptionVector.text)
298 #undef LAST
299 #define LAST .SecondaryResetVector.text
300
301 #endif
302 #ifdef CONFIG_VECTORS_OFFSET
303   SECTION_VECTOR (_exception_text,
304                   .exception.text,
305                   ,
306                   LAST)
307 #undef LAST
308 #define LAST .exception.text
309
310 #endif
311   . = (LOADADDR(LAST) + SIZEOF(LAST) + 3) & ~ 3;
312
313   . = ALIGN(PAGE_SIZE);
314
315 #ifndef CONFIG_XIP_KERNEL
316   __init_end = .;
317
318   BSS_SECTION(0, 8192, 0)
319 #endif
320
321   _end = .;
322
323 #ifdef CONFIG_XIP_KERNEL
324   . = CONFIG_XIP_DATA_ADDR;
325
326   _xip_start = .;
327
328 #undef LOAD_OFFSET
329 #define LOAD_OFFSET \
330   (CONFIG_XIP_DATA_ADDR - (LOADADDR(.dummy) + SIZEOF(.dummy) + 3) & ~ 3)
331
332   _xip_data_start = .;
333   _sdata = .;
334   RW_DATA(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE)
335   _edata = .;
336   _xip_data_end = .;
337
338   /* Initialization data: */
339
340   STRUCT_ALIGN();
341
342   _xip_init_data_start = .;
343   __init_begin = .;
344   .init.data :
345   {
346     INIT_DATA
347   }
348   _xip_init_data_end = .;
349   __init_end = .;
350   BSS_SECTION(0, 8192, 0)
351
352   _xip_end = .;
353
354 #undef LOAD_OFFSET
355 #endif
356
357   DWARF_DEBUG
358
359   .xt.prop 0 : { KEEP(*(.xt.prop .xt.prop.* .gnu.linkonce.prop.*)) }
360   .xt.insn 0 : { KEEP(*(.xt.insn .xt.insn.* .gnu.linkonce.x*)) }
361   .xt.lit  0 : { KEEP(*(.xt.lit  .xt.lit.*  .gnu.linkonce.p*)) }
362
363   /* Sections to be discarded */
364   DISCARDS
365 }