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 /* Data section */ 150 151 _sdata = .; 152 RW_DATA_SECTION(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE) 153 _edata = .; 154 155 /* Initialization code and data: */ 156 157 . = ALIGN(PAGE_SIZE); 158 __init_begin = .; 159 INIT_TEXT_SECTION(PAGE_SIZE) 160 161 .init.data : 162 { 163 INIT_DATA 164 . = ALIGN(0x4); 165 __tagtable_begin = .; 166 *(.taglist) 167 __tagtable_end = .; 168 169 . = ALIGN(16); 170 __boot_reloc_table_start = ABSOLUTE(.); 171 172#ifdef CONFIG_VECTORS_OFFSET 173 RELOCATE_ENTRY(_WindowVectors_text, 174 .WindowVectors.text); 175#if XCHAL_EXCM_LEVEL >= 2 176 RELOCATE_ENTRY(_Level2InterruptVector_text, 177 .Level2InterruptVector.text); 178#endif 179#if XCHAL_EXCM_LEVEL >= 3 180 RELOCATE_ENTRY(_Level3InterruptVector_text, 181 .Level3InterruptVector.text); 182#endif 183#if XCHAL_EXCM_LEVEL >= 4 184 RELOCATE_ENTRY(_Level4InterruptVector_text, 185 .Level4InterruptVector.text); 186#endif 187#if XCHAL_EXCM_LEVEL >= 5 188 RELOCATE_ENTRY(_Level5InterruptVector_text, 189 .Level5InterruptVector.text); 190#endif 191#if XCHAL_EXCM_LEVEL >= 6 192 RELOCATE_ENTRY(_Level6InterruptVector_text, 193 .Level6InterruptVector.text); 194#endif 195 RELOCATE_ENTRY(_KernelExceptionVector_text, 196 .KernelExceptionVector.text); 197 RELOCATE_ENTRY(_UserExceptionVector_text, 198 .UserExceptionVector.text); 199 RELOCATE_ENTRY(_DoubleExceptionVector_literal, 200 .DoubleExceptionVector.literal); 201 RELOCATE_ENTRY(_DoubleExceptionVector_text, 202 .DoubleExceptionVector.text); 203 RELOCATE_ENTRY(_DebugInterruptVector_text, 204 .DebugInterruptVector.text); 205#endif 206#if defined(CONFIG_SMP) 207 RELOCATE_ENTRY(_SecondaryResetVector_text, 208 .SecondaryResetVector.text); 209#endif 210 211 212 __boot_reloc_table_end = ABSOLUTE(.) ; 213 214 INIT_SETUP(XCHAL_ICACHE_LINESIZE) 215 INIT_CALLS 216 CON_INITCALL 217 SECURITY_INITCALL 218 INIT_RAM_FS 219 } 220 221 PERCPU_SECTION(XCHAL_ICACHE_LINESIZE) 222 223 /* We need this dummy segment here */ 224 225 . = ALIGN(4); 226 .dummy : { LONG(0) } 227 228#ifdef CONFIG_VECTORS_OFFSET 229 /* The vectors are relocated to the real position at startup time */ 230 231 SECTION_VECTOR (_WindowVectors_text, 232 .WindowVectors.text, 233 WINDOW_VECTORS_VADDR, 4, 234 .dummy) 235 SECTION_VECTOR (_DebugInterruptVector_literal, 236 .DebugInterruptVector.literal, 237 DEBUG_VECTOR_VADDR - 4, 238 SIZEOF(.WindowVectors.text), 239 .WindowVectors.text) 240 SECTION_VECTOR (_DebugInterruptVector_text, 241 .DebugInterruptVector.text, 242 DEBUG_VECTOR_VADDR, 243 4, 244 .DebugInterruptVector.literal) 245#undef LAST 246#define LAST .DebugInterruptVector.text 247#if XCHAL_EXCM_LEVEL >= 2 248 SECTION_VECTOR (_Level2InterruptVector_text, 249 .Level2InterruptVector.text, 250 INTLEVEL2_VECTOR_VADDR, 251 SIZEOF(LAST), LAST) 252# undef LAST 253# define LAST .Level2InterruptVector.text 254#endif 255#if XCHAL_EXCM_LEVEL >= 3 256 SECTION_VECTOR (_Level3InterruptVector_text, 257 .Level3InterruptVector.text, 258 INTLEVEL3_VECTOR_VADDR, 259 SIZEOF(LAST), LAST) 260# undef LAST 261# define LAST .Level3InterruptVector.text 262#endif 263#if XCHAL_EXCM_LEVEL >= 4 264 SECTION_VECTOR (_Level4InterruptVector_text, 265 .Level4InterruptVector.text, 266 INTLEVEL4_VECTOR_VADDR, 267 SIZEOF(LAST), LAST) 268# undef LAST 269# define LAST .Level4InterruptVector.text 270#endif 271#if XCHAL_EXCM_LEVEL >= 5 272 SECTION_VECTOR (_Level5InterruptVector_text, 273 .Level5InterruptVector.text, 274 INTLEVEL5_VECTOR_VADDR, 275 SIZEOF(LAST), LAST) 276# undef LAST 277# define LAST .Level5InterruptVector.text 278#endif 279#if XCHAL_EXCM_LEVEL >= 6 280 SECTION_VECTOR (_Level6InterruptVector_text, 281 .Level6InterruptVector.text, 282 INTLEVEL6_VECTOR_VADDR, 283 SIZEOF(LAST), LAST) 284# undef LAST 285# define LAST .Level6InterruptVector.text 286#endif 287 SECTION_VECTOR (_KernelExceptionVector_literal, 288 .KernelExceptionVector.literal, 289 KERNEL_VECTOR_VADDR - 4, 290 SIZEOF(LAST), LAST) 291#undef LAST 292 SECTION_VECTOR (_KernelExceptionVector_text, 293 .KernelExceptionVector.text, 294 KERNEL_VECTOR_VADDR, 295 4, 296 .KernelExceptionVector.literal) 297 SECTION_VECTOR (_UserExceptionVector_literal, 298 .UserExceptionVector.literal, 299 USER_VECTOR_VADDR - 4, 300 SIZEOF(.KernelExceptionVector.text), 301 .KernelExceptionVector.text) 302 SECTION_VECTOR (_UserExceptionVector_text, 303 .UserExceptionVector.text, 304 USER_VECTOR_VADDR, 305 4, 306 .UserExceptionVector.literal) 307 SECTION_VECTOR (_DoubleExceptionVector_literal, 308 .DoubleExceptionVector.literal, 309 DOUBLEEXC_VECTOR_VADDR - 20, 310 SIZEOF(.UserExceptionVector.text), 311 .UserExceptionVector.text) 312 SECTION_VECTOR (_DoubleExceptionVector_text, 313 .DoubleExceptionVector.text, 314 DOUBLEEXC_VECTOR_VADDR, 315 20, 316 .DoubleExceptionVector.literal) 317 318 . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; 319 320#endif 321#if defined(CONFIG_SMP) 322 323 SECTION_VECTOR (_SecondaryResetVector_text, 324 .SecondaryResetVector.text, 325 RESET_VECTOR1_VADDR, 326 SIZEOF(.DoubleExceptionVector.text), 327 .DoubleExceptionVector.text) 328 329 . = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text); 330 331#endif 332 333 . = ALIGN(PAGE_SIZE); 334 335 __init_end = .; 336 337 BSS_SECTION(0, 8192, 0) 338 339 _end = .; 340 341 .xt.lit : { *(.xt.lit) } 342 .xt.prop : { *(.xt.prop) } 343 344 .debug 0 : { *(.debug) } 345 .line 0 : { *(.line) } 346 .debug_srcinfo 0 : { *(.debug_srcinfo) } 347 .debug_sfnames 0 : { *(.debug_sfnames) } 348 .debug_aranges 0 : { *(.debug_aranges) } 349 .debug_pubnames 0 : { *(.debug_pubnames) } 350 .debug_info 0 : { *(.debug_info) } 351 .debug_abbrev 0 : { *(.debug_abbrev) } 352 .debug_line 0 : { *(.debug_line) } 353 .debug_frame 0 : { *(.debug_frame) } 354 .debug_str 0 : { *(.debug_str) } 355 .debug_loc 0 : { *(.debug_loc) } 356 .debug_macinfo 0 : { *(.debug_macinfo) } 357 .debug_weaknames 0 : { *(.debug_weaknames) } 358 .debug_funcnames 0 : { *(.debug_funcnames) } 359 .debug_typenames 0 : { *(.debug_typenames) } 360 .debug_varnames 0 : { *(.debug_varnames) } 361 362 .xt.insn 0 : 363 { 364 *(.xt.insn) 365 *(.gnu.linkonce.x*) 366 } 367 368 .xt.lit 0 : 369 { 370 *(.xt.lit) 371 *(.gnu.linkonce.p*) 372 } 373 374 /* Sections to be discarded */ 375 DISCARDS 376 /DISCARD/ : { *(.exit.literal) } 377} 378