1/* 2 * arch/xtensa/kernel/head.S 3 * 4 * Xtensa Processor startup code. 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 * Kevin Chea 16 */ 17 18#include <asm/processor.h> 19#include <asm/page.h> 20#include <asm/cacheasm.h> 21#include <asm/initialize_mmu.h> 22#include <asm/mxregs.h> 23 24#include <linux/init.h> 25#include <linux/linkage.h> 26 27/* 28 * This module contains the entry code for kernel images. It performs the 29 * minimal setup needed to call the generic C routines. 30 * 31 * Prerequisites: 32 * 33 * - The kernel image has been loaded to the actual address where it was 34 * compiled to. 35 * - a2 contains either 0 or a pointer to a list of boot parameters. 36 * (see setup.c for more details) 37 * 38 */ 39 40/* 41 * _start 42 * 43 * The bootloader passes a pointer to a list of boot parameters in a2. 44 */ 45 46 /* The first bytes of the kernel image must be an instruction, so we 47 * manually allocate and define the literal constant we need for a jx 48 * instruction. 49 */ 50 51 __HEAD 52 .begin no-absolute-literals 53 54ENTRY(_start) 55 56 /* Preserve the pointer to the boot parameter list in EXCSAVE_1 */ 57 wsr a2, excsave1 58 _j _SetupOCD 59 60 .align 4 61 .literal_position 62_SetupOCD: 63 /* 64 * Initialize WB, WS, and clear PS.EXCM (to allow loop instructions). 65 * Set Interrupt Level just below XCHAL_DEBUGLEVEL to allow 66 * xt-gdb to single step via DEBUG exceptions received directly 67 * by ocd. 68 */ 69 movi a1, 1 70 movi a0, 0 71 wsr a1, windowstart 72 wsr a0, windowbase 73 rsync 74 75 movi a1, LOCKLEVEL 76 wsr a1, ps 77 rsync 78 79 .global _SetupMMU 80_SetupMMU: 81 Offset = _SetupMMU - _start 82 83#ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX 84 initialize_mmu 85#if defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY 86 rsr a2, excsave1 87 movi a3, XCHAL_KSEG_PADDR 88 bltu a2, a3, 1f 89 sub a2, a2, a3 90 movi a3, XCHAL_KSEG_SIZE 91 bgeu a2, a3, 1f 92 movi a3, XCHAL_KSEG_CACHED_VADDR 93 add a2, a2, a3 94 wsr a2, excsave1 951: 96#endif 97#endif 98 99 movi a0, _startup 100 jx a0 101 102ENDPROC(_start) 103 .end no-absolute-literals 104 105 __REF 106 .literal_position 107 108ENTRY(_startup) 109 110 /* Set a0 to 0 for the remaining initialization. */ 111 112 movi a0, 0 113 114#if XCHAL_HAVE_VECBASE 115 movi a2, VECBASE_VADDR 116 wsr a2, vecbase 117#endif 118 119 /* Clear debugging registers. */ 120 121#if XCHAL_HAVE_DEBUG 122#if XCHAL_NUM_IBREAK > 0 123 wsr a0, ibreakenable 124#endif 125 wsr a0, icount 126 movi a1, 15 127 wsr a0, icountlevel 128 129 .set _index, 0 130 .rept XCHAL_NUM_DBREAK 131 wsr a0, SREG_DBREAKC + _index 132 .set _index, _index + 1 133 .endr 134#endif 135 136 /* Clear CCOUNT (not really necessary, but nice) */ 137 138 wsr a0, ccount # not really necessary, but nice 139 140 /* Disable zero-loops. */ 141 142#if XCHAL_HAVE_LOOPS 143 wsr a0, lcount 144#endif 145 146 /* Disable all timers. */ 147 148 .set _index, 0 149 .rept XCHAL_NUM_TIMERS 150 wsr a0, SREG_CCOMPARE + _index 151 .set _index, _index + 1 152 .endr 153 154 /* Interrupt initialization. */ 155 156 movi a2, XCHAL_INTTYPE_MASK_SOFTWARE | XCHAL_INTTYPE_MASK_EXTERN_EDGE 157 wsr a0, intenable 158 wsr a2, intclear 159 160 /* Disable coprocessors. */ 161 162#if XCHAL_HAVE_CP 163 wsr a0, cpenable 164#endif 165 166 /* Initialize the caches. 167 * a2, a3 are just working registers (clobbered). 168 */ 169 170#if XCHAL_DCACHE_LINE_LOCKABLE 171 ___unlock_dcache_all a2 a3 172#endif 173 174#if XCHAL_ICACHE_LINE_LOCKABLE 175 ___unlock_icache_all a2 a3 176#endif 177 178 ___invalidate_dcache_all a2 a3 179 ___invalidate_icache_all a2 a3 180 181 isync 182 183 initialize_cacheattr 184 185#ifdef CONFIG_HAVE_SMP 186 movi a2, CCON # MX External Register to Configure Cache 187 movi a3, 1 188 wer a3, a2 189#endif 190 191 /* Setup stack and enable window exceptions (keep irqs disabled) */ 192 193 movi a1, start_info 194 l32i a1, a1, 0 195 196 movi a2, PS_WOE_MASK | LOCKLEVEL 197 # WOE=1, INTLEVEL=LOCKLEVEL, UM=0 198 wsr a2, ps # (enable reg-windows; progmode stack) 199 rsync 200 201#ifdef CONFIG_SMP 202 /* 203 * Notice that we assume with SMP that cores have PRID 204 * supported by the cores. 205 */ 206 rsr a2, prid 207 bnez a2, .Lboot_secondary 208 209#endif /* CONFIG_SMP */ 210 211 /* Unpack data sections 212 * 213 * The linker script used to build the Linux kernel image 214 * creates a table located at __boot_reloc_table_start 215 * that contans the information what data needs to be unpacked. 216 * 217 * Uses a2-a7. 218 */ 219 220 movi a2, __boot_reloc_table_start 221 movi a3, __boot_reloc_table_end 222 2231: beq a2, a3, 3f # no more entries? 224 l32i a4, a2, 0 # start destination (in RAM) 225 l32i a5, a2, 4 # end desination (in RAM) 226 l32i a6, a2, 8 # start source (in ROM) 227 addi a2, a2, 12 # next entry 228 beq a4, a5, 1b # skip, empty entry 229 beq a4, a6, 1b # skip, source and dest. are the same 230 2312: l32i a7, a6, 0 # load word 232 addi a6, a6, 4 233 s32i a7, a4, 0 # store word 234 addi a4, a4, 4 235 bltu a4, a5, 2b 236 j 1b 237 2383: 239 /* All code and initialized data segments have been copied. 240 * Now clear the BSS segment. 241 */ 242 243 movi a2, __bss_start # start of BSS 244 movi a3, __bss_stop # end of BSS 245 246 __loopt a2, a3, a4, 2 247 s32i a0, a2, 0 248 __endla a2, a3, 4 249 250#if XCHAL_DCACHE_IS_WRITEBACK 251 252 /* After unpacking, flush the writeback cache to memory so the 253 * instructions/data are available. 254 */ 255 256 ___flush_dcache_all a2 a3 257#endif 258 memw 259 isync 260 ___invalidate_icache_all a2 a3 261 isync 262 263#ifdef CONFIG_XIP_KERNEL 264 /* Setup bootstrap CPU stack in XIP kernel */ 265 266 movi a1, start_info 267 l32i a1, a1, 0 268#endif 269 270 movi a6, 0 271 xsr a6, excsave1 272 273 /* init_arch kick-starts the linux kernel */ 274 275 call4 init_arch 276 call4 start_kernel 277 278should_never_return: 279 j should_never_return 280 281#ifdef CONFIG_SMP 282.Lboot_secondary: 283 284 movi a2, cpu_start_ccount 2851: 286 memw 287 l32i a3, a2, 0 288 beqi a3, 0, 1b 289 movi a3, 0 290 s32i a3, a2, 0 2911: 292 memw 293 l32i a3, a2, 0 294 beqi a3, 0, 1b 295 wsr a3, ccount 296 movi a3, 0 297 s32i a3, a2, 0 298 memw 299 300 movi a6, 0 301 wsr a6, excsave1 302 303 call4 secondary_start_kernel 304 j should_never_return 305 306#endif /* CONFIG_SMP */ 307 308ENDPROC(_startup) 309 310#ifdef CONFIG_HOTPLUG_CPU 311 312ENTRY(cpu_restart) 313 314#if XCHAL_DCACHE_IS_WRITEBACK 315 ___flush_invalidate_dcache_all a2 a3 316#else 317 ___invalidate_dcache_all a2 a3 318#endif 319 memw 320 movi a2, CCON # MX External Register to Configure Cache 321 movi a3, 0 322 wer a3, a2 323 extw 324 325 rsr a0, prid 326 neg a2, a0 327 movi a3, cpu_start_id 328 memw 329 s32i a2, a3, 0 330#if XCHAL_DCACHE_IS_WRITEBACK 331 dhwbi a3, 0 332#endif 3331: 334 memw 335 l32i a2, a3, 0 336 dhi a3, 0 337 bne a2, a0, 1b 338 339 /* 340 * Initialize WB, WS, and clear PS.EXCM (to allow loop instructions). 341 * Set Interrupt Level just below XCHAL_DEBUGLEVEL to allow 342 * xt-gdb to single step via DEBUG exceptions received directly 343 * by ocd. 344 */ 345 movi a1, 1 346 movi a0, 0 347 wsr a1, windowstart 348 wsr a0, windowbase 349 rsync 350 351 movi a1, LOCKLEVEL 352 wsr a1, ps 353 rsync 354 355 j _startup 356 357ENDPROC(cpu_restart) 358 359#endif /* CONFIG_HOTPLUG_CPU */ 360 361/* 362 * DATA section 363 */ 364 365 __REFDATA 366 .align 4 367ENTRY(start_info) 368 .long init_thread_union + KERNEL_STACK_SIZE 369 370/* 371 * BSS section 372 */ 373 374__PAGE_ALIGNED_BSS 375#ifdef CONFIG_MMU 376ENTRY(swapper_pg_dir) 377 .fill PAGE_SIZE, 1, 0 378END(swapper_pg_dir) 379#endif 380ENTRY(empty_zero_page) 381 .fill PAGE_SIZE, 1, 0 382END(empty_zero_page) 383