1 /* 1 /* 2 * arch/xtensa/kernel/head.S << 3 * << 4 * Xtensa Processor startup code. << 5 * << 6 * This file is subject to the terms and condi 2 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the mai 3 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 4 * for more details. 9 * 5 * 10 * Copyright (C) 2001 - 2008 Tensilica Inc. !! 6 * Copyright (C) 1994, 1995 Waldorf Electronics >> 7 * Written by Ralf Baechle and Andreas Busse >> 8 * Copyright (C) 1995 - 1999 Ralf Baechle >> 9 * Copyright (C) 1996 Paul M. Antoine >> 10 * Modified for DECStation and hence R3000 support by Paul M. Antoine >> 11 * Further modifications by David S. Miller and Harald Koerfgen >> 12 * Copyright (C) 1999 Silicon Graphics, Inc. 11 * 13 * 12 * Chris Zankel <chris@zankel.net> !! 14 * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com 13 * Marc Gauthier <marc@tensilica.com, marc@alum !! 15 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. 14 * Joe Taylor <joe@tensilica.com, joetylr@yahoo << 15 * Kevin Chea << 16 */ 16 */ 17 !! 17 #include <linux/config.h> 18 #include <asm/asmmacro.h> << 19 #include <asm/processor.h> << 20 #include <asm/page.h> << 21 #include <asm/cacheasm.h> << 22 #include <asm/initialize_mmu.h> << 23 #include <asm/mxregs.h> << 24 << 25 #include <linux/init.h> 18 #include <linux/init.h> 26 #include <linux/linkage.h> !! 19 #include <linux/threads.h> 27 << 28 /* << 29 * This module contains the entry code for ker << 30 * minimal setup needed to call the generic C << 31 * << 32 * Prerequisites: << 33 * << 34 * - The kernel image has been loaded to the a << 35 * compiled to. << 36 * - a2 contains either 0 or a pointer to a li << 37 * (see setup.c for more details) << 38 * << 39 */ << 40 20 41 /* !! 21 #include <asm/asm.h> 42 * _start !! 22 #include <asm/current.h> 43 * !! 23 #include <asm/offset.h> 44 * The bootloader passes a pointer to a list !! 24 #include <asm/pgtable-bits.h> 45 */ !! 25 #include <asm/processor.h> 46 !! 26 #include <asm/regdef.h> 47 /* The first bytes of the kernel image !! 27 #include <asm/cachectl.h> 48 * manually allocate and define the li !! 28 #include <asm/mipsregs.h> 49 * instruction. !! 29 #include <asm/stackframe.h> 50 */ !! 30 51 !! 31 .text 52 __HEAD !! 32 /* 53 .begin no-absolute-literals !! 33 * Reserved space for exception handlers. 54 !! 34 * Necessary for machines which link their kernels at KSEG0. 55 ENTRY(_start) !! 35 */ 56 !! 36 .fill 0x400 57 /* Preserve the pointer to the boot pa !! 37 58 wsr a2, excsave1 !! 38 /* The following two symbols are used for kernel profiling. */ 59 _j _SetupOCD !! 39 EXPORT(stext) 60 !! 40 EXPORT(_stext) 61 .align 4 !! 41 62 .literal_position !! 42 __INIT 63 _SetupOCD: !! 43 64 /* !! 44 /* Cache Error */ 65 * Initialize WB, WS, and clear PS.EXC !! 45 LEAF(except_vec2_generic) 66 * Set Interrupt Level just below XCHA !! 46 .set noreorder 67 * xt-gdb to single step via DEBUG exc !! 47 .set noat 68 * by ocd. !! 48 .set mips0 69 */ !! 49 /* 70 #if XCHAL_HAVE_WINDOWED !! 50 * This is a very bad place to be. Our cache error 71 movi a1, 1 !! 51 * detection has triggered. If we have write-back data 72 movi a0, 0 !! 52 * in the cache, we may not be able to recover. As a 73 wsr a1, windowstart !! 53 * first-order desperate measure, turn off KSEG0 cacheing. 74 wsr a0, windowbase !! 54 */ 75 rsync !! 55 mfc0 k0,CP0_CONFIG 76 #endif !! 56 li k1,~CONF_CM_CMASK 77 !! 57 and k0,k0,k1 78 movi a1, LOCKLEVEL !! 58 ori k0,k0,CONF_CM_UNCACHED 79 wsr a1, ps !! 59 mtc0 k0,CP0_CONFIG 80 rsync !! 60 /* Give it a few cycles to sink in... */ 81 !! 61 nop 82 .global _SetupMMU !! 62 nop 83 _SetupMMU: !! 63 nop 84 Offset = _SetupMMU - _start !! 64 85 !! 65 j cache_parity_error 86 #ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VML !! 66 nop 87 initialize_mmu !! 67 END(except_vec2_generic) 88 #if defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU !! 68 89 rsr a2, excsave1 !! 69 .set at 90 movi a3, XCHAL_KSEG_PADDR !! 70 91 bltu a2, a3, 1f !! 71 /* 92 sub a2, a2, a3 !! 72 * Special interrupt vector for embedded MIPS. This is a 93 movi a3, XCHAL_KSEG_SIZE !! 73 * dedicated interrupt vector which reduces interrupt processing 94 bgeu a2, a3, 1f !! 74 * overhead. The jump instruction will be inserted here at 95 movi a3, XCHAL_KSEG_CACHED_VADDR !! 75 * initialization time. This handler may only be 8 bytes in 96 add a2, a2, a3 !! 76 * size! 97 wsr a2, excsave1 !! 77 */ >> 78 NESTED(except_vec4, 0, sp) >> 79 1: j 1b /* Dummy, will be replaced */ >> 80 nop >> 81 END(except_vec4) >> 82 >> 83 /* >> 84 * EJTAG debug exception handler. >> 85 * The EJTAG debug exception entry point is 0xbfc00480, which >> 86 * normally is in the boot PROM, so the boot PROM must do a >> 87 * unconditional jump to this vector. >> 88 */ >> 89 NESTED(except_vec_ejtag_debug, 0, sp) >> 90 j ejtag_debug_handler >> 91 nop >> 92 END(except_vec_ejtag_debug) >> 93 >> 94 __FINIT >> 95 >> 96 /* >> 97 * EJTAG debug exception handler. >> 98 */ >> 99 NESTED(ejtag_debug_handler, PT_SIZE, sp) >> 100 .set noat >> 101 .set noreorder >> 102 mtc0 k0, CP0_DESAVE >> 103 mfc0 k0, CP0_DEBUG >> 104 >> 105 sll k0, k0, 30 # Check for SDBBP. >> 106 bgez k0, ejtag_return >> 107 >> 108 la k0, ejtag_debug_buffer >> 109 sw k1, 0(k0) >> 110 SAVE_ALL >> 111 jal ejtag_exception_handler >> 112 move a0, sp >> 113 RESTORE_ALL >> 114 la k0, ejtag_debug_buffer >> 115 lw k1, 0(k0) >> 116 >> 117 ejtag_return: >> 118 mfc0 k0, CP0_DESAVE >> 119 .set mips32 >> 120 deret >> 121 .set mips0 >> 122 nop >> 123 .set at >> 124 END(ejtag_debug_handler) >> 125 >> 126 __INIT >> 127 >> 128 /* >> 129 * NMI debug exception handler for MIPS reference boards. >> 130 * The NMI debug exception entry point is 0xbfc00000, which >> 131 * normally is in the boot PROM, so the boot PROM must do a >> 132 * unconditional jump to this vector. >> 133 */ >> 134 NESTED(except_vec_nmi, 0, sp) >> 135 j nmi_handler >> 136 nop >> 137 END(except_vec_nmi) >> 138 >> 139 __FINIT >> 140 >> 141 NESTED(nmi_handler, PT_SIZE, sp) >> 142 .set noat >> 143 .set noreorder >> 144 .set mips3 >> 145 SAVE_ALL >> 146 jal nmi_exception_handler >> 147 move a0, sp >> 148 RESTORE_ALL >> 149 eret >> 150 .set at >> 151 .set mips0 >> 152 END(nmi_handler) >> 153 >> 154 __INIT >> 155 >> 156 /* >> 157 * Kernel entry point >> 158 */ >> 159 NESTED(kernel_entry, 16, sp) >> 160 .set noreorder >> 161 >> 162 /* >> 163 * The firmware/bootloader passes argc/argp/envp >> 164 * to us as arguments. But clear bss first because >> 165 * the romvec and other important info is stored there >> 166 * by prom_init(). >> 167 */ >> 168 la t0, _edata >> 169 sw zero, (t0) >> 170 la t1, (_end - 4) 98 1: 171 1: 99 #endif !! 172 addiu t0, 4 100 #endif !! 173 bne t0, t1, 1b 101 !! 174 sw zero, (t0) 102 movi a0, _startup !! 175 103 jx a0 !! 176 /* 104 !! 177 * Stack for kernel and init, current variable 105 ENDPROC(_start) !! 178 */ 106 .end no-absolute-literals !! 179 la $28, init_task_union 107 !! 180 addiu t0, $28, KERNEL_STACK_SIZE-32 108 __REF !! 181 subu sp, t0, 4*SZREG 109 .literal_position !! 182 sw t0, kernelsp 110 !! 183 111 ENTRY(_startup) !! 184 jal init_arch 112 !! 185 nop 113 /* Set a0 to 0 for the remaining initi !! 186 END(kernel_entry) 114 << 115 movi a0, 0 << 116 << 117 #if XCHAL_HAVE_VECBASE << 118 movi a2, VECBASE_VADDR << 119 wsr a2, vecbase << 120 #endif << 121 << 122 /* Clear debugging registers. */ << 123 << 124 #if XCHAL_HAVE_DEBUG << 125 #if XCHAL_NUM_IBREAK > 0 << 126 wsr a0, ibreakenable << 127 #endif << 128 wsr a0, icount << 129 movi a1, 15 << 130 wsr a0, icountlevel << 131 << 132 .set _index, 0 << 133 .rept XCHAL_NUM_DBREAK << 134 wsr a0, SREG_DBREAKC + _index << 135 .set _index, _index + 1 << 136 .endr << 137 #endif << 138 << 139 /* Clear CCOUNT (not really necessary, << 140 << 141 wsr a0, ccount # not really n << 142 << 143 /* Disable zero-loops. */ << 144 << 145 #if XCHAL_HAVE_LOOPS << 146 wsr a0, lcount << 147 #endif << 148 << 149 /* Disable all timers. */ << 150 << 151 .set _index, 0 << 152 .rept XCHAL_NUM_TIMERS << 153 wsr a0, SREG_CCOMPARE + _index << 154 .set _index, _index + 1 << 155 .endr << 156 << 157 /* Interrupt initialization. */ << 158 << 159 movi a2, XCHAL_INTTYPE_MASK_SOFTWAR << 160 wsr a0, intenable << 161 wsr a2, intclear << 162 << 163 /* Disable coprocessors. */ << 164 << 165 #if XCHAL_HAVE_CP << 166 wsr a0, cpenable << 167 #endif << 168 187 169 /* Initialize the caches. << 170 * a2, a3 are just working registers << 171 */ << 172 << 173 #if XCHAL_DCACHE_LINE_LOCKABLE << 174 ___unlock_dcache_all a2 a3 << 175 #endif << 176 << 177 #if XCHAL_ICACHE_LINE_LOCKABLE << 178 ___unlock_icache_all a2 a3 << 179 #endif << 180 << 181 ___invalidate_dcache_all a2 a3 << 182 ___invalidate_icache_all a2 a3 << 183 << 184 isync << 185 << 186 initialize_cacheattr << 187 << 188 #ifdef CONFIG_HAVE_SMP << 189 movi a2, CCON # MX External << 190 movi a3, 1 << 191 wer a3, a2 << 192 #endif << 193 << 194 /* Setup stack and enable window excep << 195 << 196 movi a1, start_info << 197 l32i a1, a1, 0 << 198 << 199 /* Disable interrupts. */ << 200 /* Enable window exceptions if kernel << 201 movi a2, KERNEL_PS_WOE_MASK | LOCKL << 202 wsr a2, ps << 203 rsync << 204 << 205 #ifdef CONFIG_SMP << 206 /* << 207 * Notice that we assume with SMP that << 208 * supported by the cores. << 209 */ << 210 rsr a2, prid << 211 bnez a2, .Lboot_secondary << 212 << 213 #endif /* CONFIG_SMP */ << 214 << 215 /* Unpack data sections << 216 * << 217 * The linker script used to build the << 218 * creates a table located at __boot_r << 219 * that contains the information what << 220 * << 221 * Uses a2-a7. << 222 */ << 223 << 224 movi a2, __boot_reloc_table_start << 225 movi a3, __boot_reloc_table_end << 226 << 227 1: beq a2, a3, 3f # no more entr << 228 l32i a4, a2, 0 # start destin << 229 l32i a5, a2, 4 # end destinat << 230 l32i a6, a2, 8 # start source << 231 addi a2, a2, 12 # next entry << 232 beq a4, a5, 1b # skip, empty << 233 beq a4, a6, 1b # skip, source << 234 << 235 2: l32i a7, a6, 0 # load word << 236 addi a6, a6, 4 << 237 s32i a7, a4, 0 # store word << 238 addi a4, a4, 4 << 239 bltu a4, a5, 2b << 240 j 1b << 241 << 242 3: << 243 /* All code and initialized data segme << 244 * Now clear the BSS segment. << 245 */ << 246 << 247 movi a2, __bss_start # start of BSS << 248 movi a3, __bss_stop # end of BSS << 249 << 250 __loopt a2, a3, a4, 2 << 251 s32i a0, a2, 0 << 252 __endla a2, a3, 4 << 253 << 254 #if XCHAL_DCACHE_IS_WRITEBACK << 255 << 256 /* After unpacking, flush the writebac << 257 * instructions/data are available. << 258 */ << 259 << 260 ___flush_dcache_all a2 a3 << 261 #endif << 262 memw << 263 isync << 264 ___invalidate_icache_all a2 a3 << 265 isync << 266 << 267 #ifdef CONFIG_XIP_KERNEL << 268 /* Setup bootstrap CPU stack in XIP ke << 269 << 270 movi a1, start_info << 271 l32i a1, a1, 0 << 272 #endif << 273 << 274 movi abi_arg0, 0 << 275 xsr abi_arg0, excsave1 << 276 << 277 /* init_arch kick-starts the linux ker << 278 << 279 abi_call init_arch << 280 abi_call start_kernel << 281 << 282 should_never_return: << 283 j should_never_return << 284 188 285 #ifdef CONFIG_SMP 189 #ifdef CONFIG_SMP 286 .Lboot_secondary: << 287 << 288 movi a2, cpu_start_ccount << 289 1: << 290 memw << 291 l32i a3, a2, 0 << 292 beqi a3, 0, 1b << 293 movi a3, 0 << 294 s32i a3, a2, 0 << 295 1: << 296 memw << 297 l32i a3, a2, 0 << 298 beqi a3, 0, 1b << 299 wsr a3, ccount << 300 movi a3, 0 << 301 s32i a3, a2, 0 << 302 memw << 303 << 304 movi abi_arg0, 0 << 305 wsr abi_arg0, excsave1 << 306 << 307 abi_call secondary_start_kernel << 308 j should_never_return << 309 << 310 #endif /* CONFIG_SMP */ << 311 << 312 ENDPROC(_startup) << 313 << 314 #ifdef CONFIG_HOTPLUG_CPU << 315 << 316 ENTRY(cpu_restart) << 317 << 318 #if XCHAL_DCACHE_IS_WRITEBACK << 319 ___flush_invalidate_dcache_all a2 a3 << 320 #else << 321 ___invalidate_dcache_all a2 a3 << 322 #endif << 323 memw << 324 movi a2, CCON # MX External << 325 movi a3, 0 << 326 wer a3, a2 << 327 extw << 328 << 329 rsr a0, prid << 330 neg a2, a0 << 331 movi a3, cpu_start_id << 332 memw << 333 s32i a2, a3, 0 << 334 #if XCHAL_DCACHE_IS_WRITEBACK << 335 dhwbi a3, 0 << 336 #endif << 337 1: << 338 memw << 339 l32i a2, a3, 0 << 340 dhi a3, 0 << 341 bne a2, a0, 1b << 342 << 343 /* << 344 * Initialize WB, WS, and clear PS.EXC << 345 * Set Interrupt Level just below XCHA << 346 * xt-gdb to single step via DEBUG exc << 347 * by ocd. << 348 */ << 349 movi a1, 1 << 350 movi a0, 0 << 351 wsr a1, windowstart << 352 wsr a0, windowbase << 353 rsync << 354 << 355 movi a1, LOCKLEVEL << 356 wsr a1, ps << 357 rsync << 358 << 359 j _startup << 360 << 361 ENDPROC(cpu_restart) << 362 << 363 #endif /* CONFIG_HOTPLUG_CPU */ << 364 190 365 /* 191 /* 366 * DATA section !! 192 * SMP slave cpus entry point. Board specific code for bootstrap calls this >> 193 * function after setting up the stack and gp registers. 367 */ 194 */ 368 !! 195 LEAF(smp_bootstrap) 369 __REFDATA !! 196 .set push 370 .align 4 !! 197 .set noreorder 371 ENTRY(start_info) !! 198 mtc0 zero, CP0_WIRED 372 .long init_thread_union + KERNEL_STA !! 199 CLI 373 !! 200 mfc0 t0, CP0_STATUS 374 /* !! 201 li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_UX) 375 * BSS section !! 202 and t0, t1 376 */ !! 203 or t0, (ST0_CU0); 377 !! 204 jal start_secondary 378 __PAGE_ALIGNED_BSS !! 205 mtc0 t0, CP0_STATUS 379 #ifdef CONFIG_MMU !! 206 .set pop 380 ENTRY(swapper_pg_dir) !! 207 END(smp_bootstrap) 381 .fill PAGE_SIZE, 1, 0 !! 208 #endif 382 END(swapper_pg_dir) !! 209 383 #endif !! 210 __FINIT 384 ENTRY(empty_zero_page) !! 211 385 .fill PAGE_SIZE, 1, 0 !! 212 /* 386 END(empty_zero_page) !! 213 * This buffer is reserved for the use of the EJTAG debug >> 214 * handler. >> 215 */ >> 216 .data >> 217 EXPORT(ejtag_debug_buffer) >> 218 .fill 4 >> 219 >> 220 .comm kernelsp, NR_CPUS * 8, 8 >> 221 .comm pgd_current, NR_CPUS * 8, 8 >> 222 >> 223 .macro page name, order=0 >> 224 .globl \name >> 225 \name: .size \name, (_PAGE_SIZE << \order) >> 226 .org . + (_PAGE_SIZE << \order) >> 227 .type \name, @object >> 228 .endm >> 229 >> 230 .data >> 231 .align 12 >> 232 >> 233 page swapper_pg_dir, _PGD_ORDER >> 234 page empty_bad_page, 0 >> 235 page empty_bad_page_table, 0 >> 236 page invalid_pte_table, 0
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.