GNU Linux-libre 6.1.91-gnu
[releases.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 #if !defined(CONFIG_VECTORS_ADDR) && XCHAL_HAVE_VECBASE
51 #define MERGED_VECTORS 1
52 #else
53 #define MERGED_VECTORS 0
54 #endif
55
56 /*
57  * Macro to define a section for a vector. When MERGED_VECTORS is 0
58  * code for every vector is located with other init data. At startup
59  * time head.S copies code for every vector to its final position according
60  * to description recorded in the corresponding RELOCATE_ENTRY.
61  */
62
63 #define SECTION_VECTOR4(sym, section, addr, prevsec)                        \
64   section addr : AT(((LOADADDR(prevsec) + SIZEOF(prevsec)) + 3) & ~ 3)      \
65   {                                                                         \
66     . = ALIGN(4);                                                           \
67     sym ## _start = ABSOLUTE(.);                                            \
68     *(section)                                                              \
69     sym ## _end = ABSOLUTE(.);                                              \
70   }
71
72 #define SECTION_VECTOR2(section, addr)                                      \
73   . = addr;                                                                 \
74   *(section)
75
76 /*
77  *  Mapping of input sections to output sections when linking.
78  */
79
80 SECTIONS
81 {
82   . = KERNELOFFSET;
83   /* .text section */
84
85   _text = .;
86   _stext = .;
87
88   .text :
89   {
90     /* The HEAD_TEXT section must be the first section! */
91     HEAD_TEXT
92
93 #if MERGED_VECTORS
94     . = ALIGN(PAGE_SIZE);
95     _vecbase = .;
96
97 #ifdef SUPPORT_WINDOWED
98     SECTION_VECTOR2 (.WindowVectors.text, WINDOW_VECTORS_VADDR)
99 #endif
100 #if XCHAL_EXCM_LEVEL >= 2
101     SECTION_VECTOR2 (.Level2InterruptVector.text, INTLEVEL2_VECTOR_VADDR)
102 #endif
103 #if XCHAL_EXCM_LEVEL >= 3
104     SECTION_VECTOR2 (.Level3InterruptVector.text, INTLEVEL3_VECTOR_VADDR)
105 #endif
106 #if XCHAL_EXCM_LEVEL >= 4
107     SECTION_VECTOR2 (.Level4InterruptVector.text, INTLEVEL4_VECTOR_VADDR)
108 #endif
109 #if XCHAL_EXCM_LEVEL >= 5
110     SECTION_VECTOR2 (.Level5InterruptVector.text, INTLEVEL5_VECTOR_VADDR)
111 #endif
112 #if XCHAL_EXCM_LEVEL >= 6
113     SECTION_VECTOR2 (.Level6InterruptVector.text, INTLEVEL6_VECTOR_VADDR)
114 #endif
115     SECTION_VECTOR2 (.DebugInterruptVector.text, DEBUG_VECTOR_VADDR)
116     SECTION_VECTOR2 (.KernelExceptionVector.text, KERNEL_VECTOR_VADDR)
117     SECTION_VECTOR2 (.UserExceptionVector.text, USER_VECTOR_VADDR)
118     SECTION_VECTOR2 (.DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR)
119
120     *(.exception.text)
121 #endif
122
123     IRQENTRY_TEXT
124     SOFTIRQENTRY_TEXT
125     ENTRY_TEXT
126     TEXT_TEXT
127     SCHED_TEXT
128     CPUIDLE_TEXT
129     LOCK_TEXT
130     *(.fixup)
131   }
132   _etext = .;
133   PROVIDE (etext = .);
134
135   . = ALIGN(16);
136
137   RO_DATA(4096)
138
139   /* Data section */
140
141 #ifdef CONFIG_XIP_KERNEL
142   INIT_TEXT_SECTION(PAGE_SIZE)
143 #else
144   _sdata = .;
145   RW_DATA(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE)
146   _edata = .;
147
148   /* Initialization code and data: */
149
150   . = ALIGN(PAGE_SIZE);
151   __init_begin = .;
152   INIT_TEXT_SECTION(PAGE_SIZE)
153
154   .init.data :
155   {
156     INIT_DATA
157   }
158 #endif
159
160   .init.rodata :
161   {
162     . = ALIGN(0x4);
163     __tagtable_begin = .;
164     *(.taglist)
165     __tagtable_end = .;
166
167     . = ALIGN(16);
168     __boot_reloc_table_start = ABSOLUTE(.);
169
170 #if !MERGED_VECTORS
171 #ifdef SUPPORT_WINDOWED
172     RELOCATE_ENTRY(_WindowVectors_text,
173                    .WindowVectors.text);
174 #endif
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_text,
200                    .DoubleExceptionVector.text);
201     RELOCATE_ENTRY(_DebugInterruptVector_text,
202                    .DebugInterruptVector.text);
203     RELOCATE_ENTRY(_exception_text,
204                    .exception.text);
205 #endif
206 #ifdef CONFIG_XIP_KERNEL
207     RELOCATE_ENTRY(_xip_data, .data);
208     RELOCATE_ENTRY(_xip_init_data, .init.data);
209 #endif
210 #if defined(CONFIG_SECONDARY_RESET_VECTOR)
211     RELOCATE_ENTRY(_SecondaryResetVector_text,
212                    .SecondaryResetVector.text);
213 #endif
214
215     __boot_reloc_table_end = ABSOLUTE(.) ;
216
217     INIT_SETUP(XCHAL_ICACHE_LINESIZE)
218     INIT_CALLS
219     CON_INITCALL
220     INIT_RAM_FS
221   }
222
223   PERCPU_SECTION(XCHAL_ICACHE_LINESIZE)
224
225   /* We need this dummy segment here */
226
227   . = ALIGN(4);
228   .dummy : { LONG(0) }
229
230 #undef LAST
231 #define LAST    .dummy
232
233 #if !MERGED_VECTORS
234   /* The vectors are relocated to the real position at startup time */
235
236 #ifdef SUPPORT_WINDOWED
237   SECTION_VECTOR4 (_WindowVectors_text,
238                   .WindowVectors.text,
239                   WINDOW_VECTORS_VADDR,
240                   LAST)
241 #undef LAST
242 #define LAST    .WindowVectors.text
243 #endif
244   SECTION_VECTOR4 (_DebugInterruptVector_text,
245                   .DebugInterruptVector.text,
246                   DEBUG_VECTOR_VADDR,
247                   LAST)
248 #undef LAST
249 #define LAST    .DebugInterruptVector.text
250 #if XCHAL_EXCM_LEVEL >= 2
251   SECTION_VECTOR4 (_Level2InterruptVector_text,
252                   .Level2InterruptVector.text,
253                   INTLEVEL2_VECTOR_VADDR,
254                   LAST)
255 # undef LAST
256 # define LAST   .Level2InterruptVector.text
257 #endif
258 #if XCHAL_EXCM_LEVEL >= 3
259   SECTION_VECTOR4 (_Level3InterruptVector_text,
260                   .Level3InterruptVector.text,
261                   INTLEVEL3_VECTOR_VADDR,
262                   LAST)
263 # undef LAST
264 # define LAST   .Level3InterruptVector.text
265 #endif
266 #if XCHAL_EXCM_LEVEL >= 4
267   SECTION_VECTOR4 (_Level4InterruptVector_text,
268                   .Level4InterruptVector.text,
269                   INTLEVEL4_VECTOR_VADDR,
270                   LAST)
271 # undef LAST
272 # define LAST   .Level4InterruptVector.text
273 #endif
274 #if XCHAL_EXCM_LEVEL >= 5
275   SECTION_VECTOR4 (_Level5InterruptVector_text,
276                   .Level5InterruptVector.text,
277                   INTLEVEL5_VECTOR_VADDR,
278                   LAST)
279 # undef LAST
280 # define LAST   .Level5InterruptVector.text
281 #endif
282 #if XCHAL_EXCM_LEVEL >= 6
283   SECTION_VECTOR4 (_Level6InterruptVector_text,
284                   .Level6InterruptVector.text,
285                   INTLEVEL6_VECTOR_VADDR,
286                   LAST)
287 # undef LAST
288 # define LAST   .Level6InterruptVector.text
289 #endif
290   SECTION_VECTOR4 (_KernelExceptionVector_text,
291                   .KernelExceptionVector.text,
292                   KERNEL_VECTOR_VADDR,
293                   LAST)
294 #undef LAST
295   SECTION_VECTOR4 (_UserExceptionVector_text,
296                   .UserExceptionVector.text,
297                   USER_VECTOR_VADDR,
298                   .KernelExceptionVector.text)
299   SECTION_VECTOR4 (_DoubleExceptionVector_text,
300                   .DoubleExceptionVector.text,
301                   DOUBLEEXC_VECTOR_VADDR,
302                   .UserExceptionVector.text)
303 #define LAST .DoubleExceptionVector.text
304
305 #endif
306 #if defined(CONFIG_SECONDARY_RESET_VECTOR)
307
308   SECTION_VECTOR4 (_SecondaryResetVector_text,
309                   .SecondaryResetVector.text,
310                   RESET_VECTOR1_VADDR,
311                   LAST)
312 #undef LAST
313 #define LAST .SecondaryResetVector.text
314
315 #endif
316 #if !MERGED_VECTORS
317   SECTION_VECTOR4 (_exception_text,
318                   .exception.text,
319                   ,
320                   LAST)
321 #undef LAST
322 #define LAST .exception.text
323
324 #endif
325   . = (LOADADDR(LAST) + SIZEOF(LAST) + 3) & ~ 3;
326
327   .dummy1 : AT(ADDR(.dummy1)) { LONG(0) }
328   . = ALIGN(PAGE_SIZE);
329
330 #ifndef CONFIG_XIP_KERNEL
331   __init_end = .;
332
333   BSS_SECTION(0, 8192, 0)
334 #endif
335
336   _end = .;
337
338 #ifdef CONFIG_XIP_KERNEL
339   . = CONFIG_XIP_DATA_ADDR;
340
341   _xip_start = .;
342
343 #undef LOAD_OFFSET
344 #define LOAD_OFFSET \
345   (CONFIG_XIP_DATA_ADDR - (LOADADDR(.dummy1) + SIZEOF(.dummy1) + 3) & ~ 3)
346
347   _xip_data_start = .;
348   _sdata = .;
349   RW_DATA(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE)
350   _edata = .;
351   _xip_data_end = .;
352
353   /* Initialization data: */
354
355   STRUCT_ALIGN();
356
357   _xip_init_data_start = .;
358   __init_begin = .;
359   .init.data :
360   {
361     INIT_DATA
362   }
363   _xip_init_data_end = .;
364   __init_end = .;
365   BSS_SECTION(0, 8192, 0)
366
367   _xip_end = .;
368
369 #undef LOAD_OFFSET
370 #endif
371
372   DWARF_DEBUG
373
374   .xt.prop 0 : { KEEP(*(.xt.prop .xt.prop.* .gnu.linkonce.prop.*)) }
375   .xt.insn 0 : { KEEP(*(.xt.insn .xt.insn.* .gnu.linkonce.x*)) }
376   .xt.lit  0 : { KEEP(*(.xt.lit  .xt.lit.*  .gnu.linkonce.p*)) }
377
378   /* Sections to be discarded */
379   DISCARDS
380 }