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> 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/* 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 82SECTIONS 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} 379