GNU Linux-libre 4.14.303-gnu1
[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 #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>
24 OUTPUT_ARCH(xtensa)
25 ENTRY(_start)
26
27 #ifdef __XTENSA_EB__
28 jiffies = jiffies_64 + 4;
29 #else
30 jiffies = 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
82 SECTIONS
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 }