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