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 26OUTPUT_ARCH(xtensa) 27ENTRY(_start) 28 29#ifdef __XTENSA_EB__ 30jiffies = jiffies_64 + 4; 31#else 32jiffies = 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 80SECTIONS 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 LOCK_TEXT 129 *(.fixup) 130 } 131 _etext = .; 132 PROVIDE (etext = .); 133 134 . = ALIGN(16); 135 136 RO_DATA(4096) 137 138 /* Data section */ 139 140#ifdef CONFIG_XIP_KERNEL 141 INIT_TEXT_SECTION(PAGE_SIZE) 142#else 143 _sdata = .; 144 RW_DATA(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE) 145 _edata = .; 146 147 /* Initialization code and data: */ 148 149 . = ALIGN(PAGE_SIZE); 150 __init_begin = .; 151 INIT_TEXT_SECTION(PAGE_SIZE) 152 153 .init.data : 154 { 155 INIT_DATA 156 } 157#endif 158 159 .init.rodata : 160 { 161 . = ALIGN(0x4); 162 __tagtable_begin = .; 163 *(.taglist) 164 __tagtable_end = .; 165 166 . = ALIGN(16); 167 __boot_reloc_table_start = ABSOLUTE(.); 168 169#if !MERGED_VECTORS 170#ifdef SUPPORT_WINDOWED 171 RELOCATE_ENTRY(_WindowVectors_text, 172 .WindowVectors.text); 173#endif 174#if XCHAL_EXCM_LEVEL >= 2 175 RELOCATE_ENTRY(_Level2InterruptVector_text, 176 .Level2InterruptVector.text); 177#endif 178#if XCHAL_EXCM_LEVEL >= 3 179 RELOCATE_ENTRY(_Level3InterruptVector_text, 180 .Level3InterruptVector.text); 181#endif 182#if XCHAL_EXCM_LEVEL >= 4 183 RELOCATE_ENTRY(_Level4InterruptVector_text, 184 .Level4InterruptVector.text); 185#endif 186#if XCHAL_EXCM_LEVEL >= 5 187 RELOCATE_ENTRY(_Level5InterruptVector_text, 188 .Level5InterruptVector.text); 189#endif 190#if XCHAL_EXCM_LEVEL >= 6 191 RELOCATE_ENTRY(_Level6InterruptVector_text, 192 .Level6InterruptVector.text); 193#endif 194 RELOCATE_ENTRY(_KernelExceptionVector_text, 195 .KernelExceptionVector.text); 196 RELOCATE_ENTRY(_UserExceptionVector_text, 197 .UserExceptionVector.text); 198 RELOCATE_ENTRY(_DoubleExceptionVector_text, 199 .DoubleExceptionVector.text); 200 RELOCATE_ENTRY(_DebugInterruptVector_text, 201 .DebugInterruptVector.text); 202 RELOCATE_ENTRY(_exception_text, 203 .exception.text); 204#endif 205#ifdef CONFIG_XIP_KERNEL 206 RELOCATE_ENTRY(_xip_data, .data); 207 RELOCATE_ENTRY(_xip_init_data, .init.data); 208#endif 209#if defined(CONFIG_SECONDARY_RESET_VECTOR) 210 RELOCATE_ENTRY(_SecondaryResetVector_text, 211 .SecondaryResetVector.text); 212#endif 213 214 __boot_reloc_table_end = ABSOLUTE(.) ; 215 216 INIT_SETUP(XCHAL_ICACHE_LINESIZE) 217 INIT_CALLS 218 CON_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#undef LAST 230#define LAST .dummy 231 232#if !MERGED_VECTORS 233 /* The vectors are relocated to the real position at startup time */ 234 235#ifdef SUPPORT_WINDOWED 236 SECTION_VECTOR4 (_WindowVectors_text, 237 .WindowVectors.text, 238 WINDOW_VECTORS_VADDR, 239 LAST) 240#undef LAST 241#define LAST .WindowVectors.text 242#endif 243 SECTION_VECTOR4 (_DebugInterruptVector_text, 244 .DebugInterruptVector.text, 245 DEBUG_VECTOR_VADDR, 246 LAST) 247#undef LAST 248#define LAST .DebugInterruptVector.text 249#if XCHAL_EXCM_LEVEL >= 2 250 SECTION_VECTOR4 (_Level2InterruptVector_text, 251 .Level2InterruptVector.text, 252 INTLEVEL2_VECTOR_VADDR, 253 LAST) 254# undef LAST 255# define LAST .Level2InterruptVector.text 256#endif 257#if XCHAL_EXCM_LEVEL >= 3 258 SECTION_VECTOR4 (_Level3InterruptVector_text, 259 .Level3InterruptVector.text, 260 INTLEVEL3_VECTOR_VADDR, 261 LAST) 262# undef LAST 263# define LAST .Level3InterruptVector.text 264#endif 265#if XCHAL_EXCM_LEVEL >= 4 266 SECTION_VECTOR4 (_Level4InterruptVector_text, 267 .Level4InterruptVector.text, 268 INTLEVEL4_VECTOR_VADDR, 269 LAST) 270# undef LAST 271# define LAST .Level4InterruptVector.text 272#endif 273#if XCHAL_EXCM_LEVEL >= 5 274 SECTION_VECTOR4 (_Level5InterruptVector_text, 275 .Level5InterruptVector.text, 276 INTLEVEL5_VECTOR_VADDR, 277 LAST) 278# undef LAST 279# define LAST .Level5InterruptVector.text 280#endif 281#if XCHAL_EXCM_LEVEL >= 6 282 SECTION_VECTOR4 (_Level6InterruptVector_text, 283 .Level6InterruptVector.text, 284 INTLEVEL6_VECTOR_VADDR, 285 LAST) 286# undef LAST 287# define LAST .Level6InterruptVector.text 288#endif 289 SECTION_VECTOR4 (_KernelExceptionVector_text, 290 .KernelExceptionVector.text, 291 KERNEL_VECTOR_VADDR, 292 LAST) 293#undef LAST 294 SECTION_VECTOR4 (_UserExceptionVector_text, 295 .UserExceptionVector.text, 296 USER_VECTOR_VADDR, 297 .KernelExceptionVector.text) 298 SECTION_VECTOR4 (_DoubleExceptionVector_text, 299 .DoubleExceptionVector.text, 300 DOUBLEEXC_VECTOR_VADDR, 301 .UserExceptionVector.text) 302#define LAST .DoubleExceptionVector.text 303 304#endif 305#if defined(CONFIG_SECONDARY_RESET_VECTOR) 306 307 SECTION_VECTOR4 (_SecondaryResetVector_text, 308 .SecondaryResetVector.text, 309 RESET_VECTOR1_VADDR, 310 LAST) 311#undef LAST 312#define LAST .SecondaryResetVector.text 313 314#endif 315#if !MERGED_VECTORS 316 SECTION_VECTOR4 (_exception_text, 317 .exception.text, 318 , 319 LAST) 320#undef LAST 321#define LAST .exception.text 322 323#endif 324 . = (LOADADDR(LAST) + SIZEOF(LAST) + 3) & ~ 3; 325 326 .dummy1 : AT(ADDR(.dummy1)) { LONG(0) } 327 . = ALIGN(PAGE_SIZE); 328 329#ifndef CONFIG_XIP_KERNEL 330 __init_end = .; 331 332 BSS_SECTION(0, 8192, 0) 333#endif 334 335 _end = .; 336 337#ifdef CONFIG_XIP_KERNEL 338 . = CONFIG_XIP_DATA_ADDR; 339 340 _xip_start = .; 341 342#undef LOAD_OFFSET 343#define LOAD_OFFSET \ 344 (CONFIG_XIP_DATA_ADDR - (LOADADDR(.dummy1) + SIZEOF(.dummy1) + 3) & ~ 3) 345 346 _xip_data_start = .; 347 _sdata = .; 348 RW_DATA(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE) 349 _edata = .; 350 _xip_data_end = .; 351 352 /* Initialization data: */ 353 354 STRUCT_ALIGN(); 355 356 _xip_init_data_start = .; 357 __init_begin = .; 358 .init.data : 359 { 360 INIT_DATA 361 } 362 _xip_init_data_end = .; 363 __init_end = .; 364 BSS_SECTION(0, 8192, 0) 365 366 _xip_end = .; 367 368#undef LOAD_OFFSET 369#endif 370 371 DWARF_DEBUG 372 373 .xt.prop 0 : { KEEP(*(.xt.prop .xt.prop.* .gnu.linkonce.prop.*)) } 374 .xt.insn 0 : { KEEP(*(.xt.insn .xt.insn.* .gnu.linkonce.x*)) } 375 .xt.lit 0 : { KEEP(*(.xt.lit .xt.lit.* .gnu.linkonce.p*)) } 376 377 /* Sections to be discarded */ 378 DISCARDS 379} 380