Merge tag 'xtensa-20181101' of git://github.com/jcmvbkbc/linux-xtensa
[linux-2.6-microblaze.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
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 /*
49  * Macro to define a section for a vector. When CONFIG_VECTORS_OFFSET is
50  * defined code for every vector is located with other init data. At startup
51  * time head.S copies code for every vector to its final position according
52  * to description recorded in the corresponding RELOCATE_ENTRY.
53  */
54
55 #ifdef CONFIG_VECTORS_OFFSET
56 #define SECTION_VECTOR(sym, section, addr, prevsec)                         \
57   section addr : AT(((LOADADDR(prevsec) + SIZEOF(prevsec)) + 3) & ~ 3)      \
58   {                                                                         \
59     . = ALIGN(4);                                                           \
60     sym ## _start = ABSOLUTE(.);                                            \
61     *(section)                                                              \
62     sym ## _end = ABSOLUTE(.);                                              \
63   }
64 #else
65 #define SECTION_VECTOR(section, addr)                                       \
66   . = addr;                                                                 \
67   *(section)
68 #endif
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_VECTOR (.WindowVectors.text, WINDOW_VECTORS_VADDR)
92 #if XCHAL_EXCM_LEVEL >= 2
93   SECTION_VECTOR (.Level2InterruptVector.text, INTLEVEL2_VECTOR_VADDR)
94 #endif
95 #if XCHAL_EXCM_LEVEL >= 3
96   SECTION_VECTOR (.Level3InterruptVector.text, INTLEVEL3_VECTOR_VADDR)
97 #endif
98 #if XCHAL_EXCM_LEVEL >= 4
99   SECTION_VECTOR (.Level4InterruptVector.text, INTLEVEL4_VECTOR_VADDR)
100 #endif
101 #if XCHAL_EXCM_LEVEL >= 5
102   SECTION_VECTOR (.Level5InterruptVector.text, INTLEVEL5_VECTOR_VADDR)
103 #endif
104 #if XCHAL_EXCM_LEVEL >= 6
105   SECTION_VECTOR (.Level6InterruptVector.text, INTLEVEL6_VECTOR_VADDR)
106 #endif
107   SECTION_VECTOR (.DebugInterruptVector.text, DEBUG_VECTOR_VADDR)
108   SECTION_VECTOR (.KernelExceptionVector.text, KERNEL_VECTOR_VADDR)
109   SECTION_VECTOR (.UserExceptionVector.text, USER_VECTOR_VADDR)
110   SECTION_VECTOR (.DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR)
111 #endif
112
113     IRQENTRY_TEXT
114     SOFTIRQENTRY_TEXT
115     ENTRY_TEXT
116     TEXT_TEXT
117     SCHED_TEXT
118     CPUIDLE_TEXT
119     LOCK_TEXT
120
121   }
122   _etext = .;
123   PROVIDE (etext = .);
124
125   . = ALIGN(16);
126
127   RODATA
128
129   /*  Relocation table */
130
131   .fixup   : { *(.fixup) }
132
133   EXCEPTION_TABLE(16)
134   NOTES
135   /* Data section */
136
137   _sdata = .;
138   RW_DATA_SECTION(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 }