xref: /openbmc/linux/arch/xtensa/kernel/vmlinux.lds.S (revision eaf93707)
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/core.h>
22#include <asm/vectors.h>
23
24OUTPUT_ARCH(xtensa)
25ENTRY(_start)
26
27#ifdef __XTENSA_EB__
28jiffies = jiffies_64 + 4;
29#else
30jiffies = 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
74SECTIONS
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  /* Data section */
135
136  _sdata = .;
137  RW_DATA_SECTION(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    . = ALIGN(0x4);
150    __tagtable_begin = .;
151    *(.taglist)
152    __tagtable_end = .;
153
154    . = ALIGN(16);
155    __boot_reloc_table_start = ABSOLUTE(.);
156
157#ifdef CONFIG_VECTORS_OFFSET
158    RELOCATE_ENTRY(_WindowVectors_text,
159		   .WindowVectors.text);
160#if XCHAL_EXCM_LEVEL >= 2
161    RELOCATE_ENTRY(_Level2InterruptVector_text,
162		   .Level2InterruptVector.text);
163#endif
164#if XCHAL_EXCM_LEVEL >= 3
165    RELOCATE_ENTRY(_Level3InterruptVector_text,
166		   .Level3InterruptVector.text);
167#endif
168#if XCHAL_EXCM_LEVEL >= 4
169    RELOCATE_ENTRY(_Level4InterruptVector_text,
170		   .Level4InterruptVector.text);
171#endif
172#if XCHAL_EXCM_LEVEL >= 5
173    RELOCATE_ENTRY(_Level5InterruptVector_text,
174		   .Level5InterruptVector.text);
175#endif
176#if XCHAL_EXCM_LEVEL >= 6
177    RELOCATE_ENTRY(_Level6InterruptVector_text,
178		   .Level6InterruptVector.text);
179#endif
180    RELOCATE_ENTRY(_KernelExceptionVector_text,
181		   .KernelExceptionVector.text);
182    RELOCATE_ENTRY(_UserExceptionVector_text,
183		   .UserExceptionVector.text);
184    RELOCATE_ENTRY(_DoubleExceptionVector_text,
185		   .DoubleExceptionVector.text);
186    RELOCATE_ENTRY(_DebugInterruptVector_text,
187		   .DebugInterruptVector.text);
188#endif
189#if defined(CONFIG_SMP)
190    RELOCATE_ENTRY(_SecondaryResetVector_text,
191		   .SecondaryResetVector.text);
192#endif
193
194
195    __boot_reloc_table_end = ABSOLUTE(.) ;
196
197    INIT_SETUP(XCHAL_ICACHE_LINESIZE)
198    INIT_CALLS
199    CON_INITCALL
200    INIT_RAM_FS
201  }
202
203  PERCPU_SECTION(XCHAL_ICACHE_LINESIZE)
204
205  /* We need this dummy segment here */
206
207  . = ALIGN(4);
208  .dummy : { LONG(0) }
209
210#ifdef CONFIG_VECTORS_OFFSET
211  /* The vectors are relocated to the real position at startup time */
212
213  SECTION_VECTOR (_WindowVectors_text,
214		  .WindowVectors.text,
215		  WINDOW_VECTORS_VADDR,
216		  .dummy)
217  SECTION_VECTOR (_DebugInterruptVector_text,
218		  .DebugInterruptVector.text,
219		  DEBUG_VECTOR_VADDR,
220		  .WindowVectors.text)
221#undef LAST
222#define LAST	.DebugInterruptVector.text
223#if XCHAL_EXCM_LEVEL >= 2
224  SECTION_VECTOR (_Level2InterruptVector_text,
225		  .Level2InterruptVector.text,
226		  INTLEVEL2_VECTOR_VADDR,
227		  LAST)
228# undef LAST
229# define LAST	.Level2InterruptVector.text
230#endif
231#if XCHAL_EXCM_LEVEL >= 3
232  SECTION_VECTOR (_Level3InterruptVector_text,
233		  .Level3InterruptVector.text,
234		  INTLEVEL3_VECTOR_VADDR,
235		  LAST)
236# undef LAST
237# define LAST	.Level3InterruptVector.text
238#endif
239#if XCHAL_EXCM_LEVEL >= 4
240  SECTION_VECTOR (_Level4InterruptVector_text,
241		  .Level4InterruptVector.text,
242		  INTLEVEL4_VECTOR_VADDR,
243		  LAST)
244# undef LAST
245# define LAST	.Level4InterruptVector.text
246#endif
247#if XCHAL_EXCM_LEVEL >= 5
248  SECTION_VECTOR (_Level5InterruptVector_text,
249		  .Level5InterruptVector.text,
250		  INTLEVEL5_VECTOR_VADDR,
251		  LAST)
252# undef LAST
253# define LAST	.Level5InterruptVector.text
254#endif
255#if XCHAL_EXCM_LEVEL >= 6
256  SECTION_VECTOR (_Level6InterruptVector_text,
257		  .Level6InterruptVector.text,
258		  INTLEVEL6_VECTOR_VADDR,
259		  LAST)
260# undef LAST
261# define LAST	.Level6InterruptVector.text
262#endif
263  SECTION_VECTOR (_KernelExceptionVector_text,
264		  .KernelExceptionVector.text,
265		  KERNEL_VECTOR_VADDR,
266		  LAST)
267#undef LAST
268  SECTION_VECTOR (_UserExceptionVector_text,
269		  .UserExceptionVector.text,
270		  USER_VECTOR_VADDR,
271		  .KernelExceptionVector.text)
272  SECTION_VECTOR (_DoubleExceptionVector_text,
273		  .DoubleExceptionVector.text,
274		  DOUBLEEXC_VECTOR_VADDR,
275		  .UserExceptionVector.text)
276
277  . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
278
279#endif
280#if defined(CONFIG_SMP)
281
282  SECTION_VECTOR (_SecondaryResetVector_text,
283		  .SecondaryResetVector.text,
284		  RESET_VECTOR1_VADDR,
285		  .DoubleExceptionVector.text)
286
287  . = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text);
288
289#endif
290
291  . = ALIGN(PAGE_SIZE);
292
293  __init_end = .;
294
295  BSS_SECTION(0, 8192, 0)
296
297  _end = .;
298
299  DWARF_DEBUG
300
301  .xt.prop 0 : { KEEP(*(.xt.prop .xt.prop.* .gnu.linkonce.prop.*)) }
302  .xt.insn 0 : { KEEP(*(.xt.insn .xt.insn.* .gnu.linkonce.x*)) }
303  .xt.lit  0 : { KEEP(*(.xt.lit  .xt.lit.*  .gnu.linkonce.p*)) }
304
305  /* Sections to be discarded */
306  DISCARDS
307}
308