]> asedeno.scripts.mit.edu Git - linux.git/blob - arch/xtensa/kernel/vmlinux.lds.S
xtensa: separate SMP and XIP support
[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 #define SECTION_VECTOR4(sym, section, addr, prevsec)                        \
58   section addr : AT(((LOADADDR(prevsec) + SIZEOF(prevsec)) + 3) & ~ 3)      \
59   {                                                                         \
60     . = ALIGN(4);                                                           \
61     sym ## _start = ABSOLUTE(.);                                            \
62     *(section)                                                              \
63     sym ## _end = ABSOLUTE(.);                                              \
64   }
65
66 #define SECTION_VECTOR2(section, addr)                                      \
67   . = addr;                                                                 \
68   *(section)
69
70 /*
71  *  Mapping of input sections to output sections when linking.
72  */
73
74 SECTIONS
75 {
76   . = KERNELOFFSET;
77   /* .text section */
78
79   _text = .;
80   _stext = .;
81
82   .text :
83   {
84     /* The HEAD_TEXT section must be the first section! */
85     HEAD_TEXT
86
87 #ifndef CONFIG_VECTORS_OFFSET
88     . = ALIGN(PAGE_SIZE);
89     _vecbase = .;
90
91     SECTION_VECTOR2 (.WindowVectors.text, WINDOW_VECTORS_VADDR)
92 #if XCHAL_EXCM_LEVEL >= 2
93     SECTION_VECTOR2 (.Level2InterruptVector.text, INTLEVEL2_VECTOR_VADDR)
94 #endif
95 #if XCHAL_EXCM_LEVEL >= 3
96     SECTION_VECTOR2 (.Level3InterruptVector.text, INTLEVEL3_VECTOR_VADDR)
97 #endif
98 #if XCHAL_EXCM_LEVEL >= 4
99     SECTION_VECTOR2 (.Level4InterruptVector.text, INTLEVEL4_VECTOR_VADDR)
100 #endif
101 #if XCHAL_EXCM_LEVEL >= 5
102     SECTION_VECTOR2 (.Level5InterruptVector.text, INTLEVEL5_VECTOR_VADDR)
103 #endif
104 #if XCHAL_EXCM_LEVEL >= 6
105     SECTION_VECTOR2 (.Level6InterruptVector.text, INTLEVEL6_VECTOR_VADDR)
106 #endif
107     SECTION_VECTOR2 (.DebugInterruptVector.text, DEBUG_VECTOR_VADDR)
108     SECTION_VECTOR2 (.KernelExceptionVector.text, KERNEL_VECTOR_VADDR)
109     SECTION_VECTOR2 (.UserExceptionVector.text, USER_VECTOR_VADDR)
110     SECTION_VECTOR2 (.DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR)
111
112     *(.exception.text)
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     *(.fixup)
123   }
124   _etext = .;
125   PROVIDE (etext = .);
126
127   . = ALIGN(16);
128
129   RO_DATA(4096)
130
131   /* Data section */
132
133 #ifdef CONFIG_XIP_KERNEL
134   INIT_TEXT_SECTION(PAGE_SIZE)
135 #else
136   _sdata = .;
137   RW_DATA(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE)
138   _edata = .;
139
140   /* Initialization code and data: */
141
142   . = ALIGN(PAGE_SIZE);
143   __init_begin = .;
144   INIT_TEXT_SECTION(PAGE_SIZE)
145
146   .init.data :
147   {
148     INIT_DATA
149   }
150 #endif
151
152   .init.rodata :
153   {
154     . = ALIGN(0x4);
155     __tagtable_begin = .;
156     *(.taglist)
157     __tagtable_end = .;
158
159     . = ALIGN(16);
160     __boot_reloc_table_start = ABSOLUTE(.);
161
162 #ifdef CONFIG_VECTORS_OFFSET
163     RELOCATE_ENTRY(_WindowVectors_text,
164                    .WindowVectors.text);
165 #if XCHAL_EXCM_LEVEL >= 2
166     RELOCATE_ENTRY(_Level2InterruptVector_text,
167                    .Level2InterruptVector.text);
168 #endif
169 #if XCHAL_EXCM_LEVEL >= 3
170     RELOCATE_ENTRY(_Level3InterruptVector_text,
171                    .Level3InterruptVector.text);
172 #endif
173 #if XCHAL_EXCM_LEVEL >= 4
174     RELOCATE_ENTRY(_Level4InterruptVector_text,
175                    .Level4InterruptVector.text);
176 #endif
177 #if XCHAL_EXCM_LEVEL >= 5
178     RELOCATE_ENTRY(_Level5InterruptVector_text,
179                    .Level5InterruptVector.text);
180 #endif
181 #if XCHAL_EXCM_LEVEL >= 6
182     RELOCATE_ENTRY(_Level6InterruptVector_text,
183                    .Level6InterruptVector.text);
184 #endif
185     RELOCATE_ENTRY(_KernelExceptionVector_text,
186                    .KernelExceptionVector.text);
187     RELOCATE_ENTRY(_UserExceptionVector_text,
188                    .UserExceptionVector.text);
189     RELOCATE_ENTRY(_DoubleExceptionVector_text,
190                    .DoubleExceptionVector.text);
191     RELOCATE_ENTRY(_DebugInterruptVector_text,
192                    .DebugInterruptVector.text);
193     RELOCATE_ENTRY(_exception_text,
194                    .exception.text);
195 #endif
196 #ifdef CONFIG_XIP_KERNEL
197     RELOCATE_ENTRY(_xip_data, .data);
198     RELOCATE_ENTRY(_xip_init_data, .init.data);
199 #endif
200 #if defined(CONFIG_SMP)
201     RELOCATE_ENTRY(_SecondaryResetVector_text,
202                    .SecondaryResetVector.text);
203 #endif
204
205     __boot_reloc_table_end = ABSOLUTE(.) ;
206
207     INIT_SETUP(XCHAL_ICACHE_LINESIZE)
208     INIT_CALLS
209     CON_INITCALL
210     INIT_RAM_FS
211   }
212
213   PERCPU_SECTION(XCHAL_ICACHE_LINESIZE)
214
215   /* We need this dummy segment here */
216
217   . = ALIGN(4);
218   .dummy : { LONG(0) }
219
220 #undef LAST
221 #define LAST    .dummy
222
223 #ifdef CONFIG_VECTORS_OFFSET
224   /* The vectors are relocated to the real position at startup time */
225
226   SECTION_VECTOR4 (_WindowVectors_text,
227                   .WindowVectors.text,
228                   WINDOW_VECTORS_VADDR,
229                   .dummy)
230   SECTION_VECTOR4 (_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_VECTOR4 (_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_VECTOR4 (_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_VECTOR4 (_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_VECTOR4 (_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_VECTOR4 (_Level6InterruptVector_text,
270                   .Level6InterruptVector.text,
271                   INTLEVEL6_VECTOR_VADDR,
272                   LAST)
273 # undef LAST
274 # define LAST   .Level6InterruptVector.text
275 #endif
276   SECTION_VECTOR4 (_KernelExceptionVector_text,
277                   .KernelExceptionVector.text,
278                   KERNEL_VECTOR_VADDR,
279                   LAST)
280 #undef LAST
281   SECTION_VECTOR4 (_UserExceptionVector_text,
282                   .UserExceptionVector.text,
283                   USER_VECTOR_VADDR,
284                   .KernelExceptionVector.text)
285   SECTION_VECTOR4 (_DoubleExceptionVector_text,
286                   .DoubleExceptionVector.text,
287                   DOUBLEEXC_VECTOR_VADDR,
288                   .UserExceptionVector.text)
289 #define LAST .DoubleExceptionVector.text
290
291 #endif
292 #if defined(CONFIG_SMP)
293
294   SECTION_VECTOR4 (_SecondaryResetVector_text,
295                   .SecondaryResetVector.text,
296                   RESET_VECTOR1_VADDR,
297                   LAST)
298 #undef LAST
299 #define LAST .SecondaryResetVector.text
300
301 #endif
302 #ifdef CONFIG_VECTORS_OFFSET
303   SECTION_VECTOR4 (_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 }