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 11 * !! 7 * Written by Ralf Baechle and Andreas Busse 12 * Chris Zankel <chris@zankel.net> !! 8 * Copyright (C) 1994 - 99, 2003, 06 Ralf Baechle 13 * Marc Gauthier <marc@tensilica.com, marc@alum !! 9 * Copyright (C) 1996 Paul M. Antoine 14 * Joe Taylor <joe@tensilica.com, joetylr@yahoo !! 10 * Modified for DECStation and hence R3000 support by Paul M. Antoine 15 * Kevin Chea !! 11 * Further modifications by David S. Miller and Harald Koerfgen >> 12 * Copyright (C) 1999 Silicon Graphics, Inc. >> 13 * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com >> 14 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. 16 */ 15 */ 17 << 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> 16 #include <linux/init.h> 26 #include <linux/linkage.h> !! 17 #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 18 41 /* !! 19 #include <asm/addrspace.h> 42 * _start !! 20 #include <asm/asm.h> 43 * !! 21 #include <asm/asmmacro.h> 44 * The bootloader passes a pointer to a list !! 22 #include <asm/irqflags.h> 45 */ !! 23 #include <asm/regdef.h> 46 !! 24 #include <asm/pgtable-bits.h> 47 /* The first bytes of the kernel image !! 25 #include <asm/mipsregs.h> 48 * manually allocate and define the li !! 26 #include <asm/stackframe.h> 49 * instruction. << 50 */ << 51 << 52 __HEAD << 53 .begin no-absolute-literals << 54 27 55 ENTRY(_start) !! 28 #include <kernel-entry-init.h> 56 29 57 /* Preserve the pointer to the boot pa << 58 wsr a2, excsave1 << 59 _j _SetupOCD << 60 << 61 .align 4 << 62 .literal_position << 63 _SetupOCD: << 64 /* 30 /* 65 * Initialize WB, WS, and clear PS.EXC !! 31 * inputs are the text nasid in t1, data nasid in t2. 66 * Set Interrupt Level just below XCHA << 67 * xt-gdb to single step via DEBUG exc << 68 * by ocd. << 69 */ 32 */ 70 #if XCHAL_HAVE_WINDOWED !! 33 .macro MAPPED_KERNEL_SETUP_TLB 71 movi a1, 1 !! 34 #ifdef CONFIG_MAPPED_KERNEL 72 movi a0, 0 !! 35 /* 73 wsr a1, windowstart !! 36 * This needs to read the nasid - assume 0 for now. 74 wsr a0, windowbase !! 37 * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0, 75 rsync !! 38 * 0+DVG in tlblo_1. 76 #endif !! 39 */ 77 !! 40 dli t0, 0xffffffffc0000000 78 movi a1, LOCKLEVEL !! 41 dmtc0 t0, CP0_ENTRYHI 79 wsr a1, ps !! 42 li t0, 0x1c000 # Offset of text into node memory 80 rsync !! 43 dsll t1, NASID_SHFT # Shift text nasid into place 81 !! 44 dsll t2, NASID_SHFT # Same for data nasid 82 .global _SetupMMU !! 45 or t1, t1, t0 # Physical load address of kernel text 83 _SetupMMU: !! 46 or t2, t2, t0 # Physical load address of kernel data 84 Offset = _SetupMMU - _start !! 47 dsrl t1, 12 # 4K pfn 85 !! 48 dsrl t2, 12 # 4K pfn 86 #ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VML !! 49 dsll t1, 6 # Get pfn into place 87 initialize_mmu !! 50 dsll t2, 6 # Get pfn into place 88 #if defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU !! 51 li t0, ((_PAGE_GLOBAL|_PAGE_VALID| _CACHE_CACHABLE_COW) >> 6) 89 rsr a2, excsave1 !! 52 or t0, t0, t1 90 movi a3, XCHAL_KSEG_PADDR !! 53 mtc0 t0, CP0_ENTRYLO0 # physaddr, VG, cach exlwr 91 bltu a2, a3, 1f !! 54 li t0, ((_PAGE_GLOBAL|_PAGE_VALID| _PAGE_DIRTY|_CACHE_CACHABLE_COW) >> 6) 92 sub a2, a2, a3 !! 55 or t0, t0, t2 93 movi a3, XCHAL_KSEG_SIZE !! 56 mtc0 t0, CP0_ENTRYLO1 # physaddr, DVG, cach exlwr 94 bgeu a2, a3, 1f !! 57 li t0, 0x1ffe000 # MAPPED_KERN_TLBMASK, TLBPGMASK_16M 95 movi a3, XCHAL_KSEG_CACHED_VADDR !! 58 mtc0 t0, CP0_PAGEMASK 96 add a2, a2, a3 !! 59 li t0, 0 # KMAP_INX 97 wsr a2, excsave1 !! 60 mtc0 t0, CP0_INDEX 98 1: !! 61 li t0, 1 99 #endif !! 62 mtc0 t0, CP0_WIRED 100 #endif !! 63 tlbwi 101 !! 64 #else 102 movi a0, _startup !! 65 mtc0 zero, CP0_WIRED 103 jx a0 << 104 << 105 ENDPROC(_start) << 106 .end no-absolute-literals << 107 << 108 __REF << 109 .literal_position << 110 << 111 ENTRY(_startup) << 112 << 113 /* Set a0 to 0 for the remaining initi << 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 66 #endif >> 67 .endm 168 68 169 /* Initialize the caches. !! 69 /* 170 * a2, a3 are just working registers !! 70 * For the moment disable interrupts, mark the kernel mode and >> 71 * set ST0_KX so that the CPU does not spit fire when using >> 72 * 64-bit addresses. A full initialization of the CPU's status >> 73 * register is done later in per_cpu_trap_init(). >> 74 */ >> 75 .macro setup_c0_status set clr >> 76 .set push >> 77 #ifdef CONFIG_MIPS_MT_SMTC >> 78 /* >> 79 * For SMTC, we need to set privilege and disable interrupts only for >> 80 * the current TC, using the TCStatus register. 171 */ 81 */ 172 !! 82 mfc0 t0, CP0_TCSTATUS 173 #if XCHAL_DCACHE_LINE_LOCKABLE !! 83 /* Fortunately CU 0 is in the same place in both registers */ 174 ___unlock_dcache_all a2 a3 !! 84 /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */ 175 #endif !! 85 li t1, ST0_CU0 | 0x08001c00 176 !! 86 or t0, t1 177 #if XCHAL_ICACHE_LINE_LOCKABLE !! 87 /* Clear TKSU, leave IXMT */ 178 ___unlock_icache_all a2 a3 !! 88 xori t0, 0x00001800 >> 89 mtc0 t0, CP0_TCSTATUS >> 90 _ehb >> 91 /* We need to leave the global IE bit set, but clear EXL...*/ >> 92 mfc0 t0, CP0_STATUS >> 93 or t0, ST0_CU0 | ST0_EXL | ST0_ERL | \set | \clr >> 94 xor t0, ST0_EXL | ST0_ERL | \clr >> 95 mtc0 t0, CP0_STATUS >> 96 #else >> 97 mfc0 t0, CP0_STATUS >> 98 or t0, ST0_CU0|\set|0x1f|\clr >> 99 xor t0, 0x1f|\clr >> 100 mtc0 t0, CP0_STATUS >> 101 .set noreorder >> 102 sll zero,3 # ehb >> 103 #endif >> 104 .set pop >> 105 .endm >> 106 >> 107 .macro setup_c0_status_pri >> 108 #ifdef CONFIG_64BIT >> 109 setup_c0_status ST0_KX 0 >> 110 #else >> 111 setup_c0_status 0 0 179 #endif 112 #endif >> 113 .endm 180 114 181 ___invalidate_dcache_all a2 a3 !! 115 .macro setup_c0_status_sec 182 ___invalidate_icache_all a2 a3 !! 116 #ifdef CONFIG_64BIT 183 !! 117 setup_c0_status ST0_KX ST0_BEV 184 isync !! 118 #else 185 !! 119 setup_c0_status 0 ST0_BEV 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 120 #endif >> 121 .endm 193 122 194 /* Setup stack and enable window excep !! 123 #ifndef CONFIG_NO_EXCEPT_FILL 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 /* 124 /* 207 * Notice that we assume with SMP that !! 125 * Reserved space for exception handlers. 208 * supported by the cores. !! 126 * Necessary for machines which link their kernels at KSEG0. 209 */ 127 */ 210 rsr a2, prid !! 128 .fill 0x400 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 129 #endif 262 memw << 263 isync << 264 ___invalidate_icache_all a2 a3 << 265 isync << 266 130 267 #ifdef CONFIG_XIP_KERNEL !! 131 EXPORT(_stext) 268 /* Setup bootstrap CPU stack in XIP ke << 269 132 270 movi a1, start_info !! 133 #ifdef CONFIG_BOOT_RAW 271 l32i a1, a1, 0 !! 134 /* >> 135 * Give us a fighting chance of running if execution beings at the >> 136 * kernel load address. This is needed because this platform does >> 137 * not have a ELF loader yet. >> 138 */ >> 139 FEXPORT(__kernel_entry) >> 140 j kernel_entry 272 #endif 141 #endif 273 142 274 movi abi_arg0, 0 !! 143 __REF 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 << 285 #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 144 310 #endif /* CONFIG_SMP */ !! 145 NESTED(kernel_entry, 16, sp) # kernel entry point 311 146 312 ENDPROC(_startup) !! 147 kernel_entry_setup # cpu specific setup 313 148 314 #ifdef CONFIG_HOTPLUG_CPU !! 149 setup_c0_status_pri 315 150 316 ENTRY(cpu_restart) !! 151 /* We might not get launched at the address the kernel is linked to, 317 !! 152 so we jump there. */ 318 #if XCHAL_DCACHE_IS_WRITEBACK !! 153 PTR_LA t0, 0f 319 ___flush_invalidate_dcache_all a2 a3 !! 154 jr t0 320 #else !! 155 0: 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 156 >> 157 #ifdef CONFIG_MIPS_MT_SMTC 343 /* 158 /* 344 * Initialize WB, WS, and clear PS.EXC !! 159 * In SMTC kernel, "CLI" is thread-specific, in TCStatus. 345 * Set Interrupt Level just below XCHA !! 160 * We still need to enable interrupts globally in Status, 346 * xt-gdb to single step via DEBUG exc !! 161 * and clear EXL/ERL. 347 * by ocd. !! 162 * 348 */ !! 163 * TCContext is used to track interrupt levels under 349 movi a1, 1 !! 164 * service in SMTC kernel. Clear for boot TC before 350 movi a0, 0 !! 165 * allowing any interrupts. 351 wsr a1, windowstart !! 166 */ 352 wsr a0, windowbase !! 167 mtc0 zero, CP0_TCCONTEXT 353 rsync !! 168 354 !! 169 mfc0 t0, CP0_STATUS 355 movi a1, LOCKLEVEL !! 170 ori t0, t0, 0xff1f 356 wsr a1, ps !! 171 xori t0, t0, 0x001e 357 rsync !! 172 mtc0 t0, CP0_STATUS 358 !! 173 #endif /* CONFIG_MIPS_MT_SMTC */ 359 j _startup !! 174 >> 175 PTR_LA t0, __bss_start # clear .bss >> 176 LONG_S zero, (t0) >> 177 PTR_LA t1, __bss_stop - LONGSIZE >> 178 1: >> 179 PTR_ADDIU t0, LONGSIZE >> 180 LONG_S zero, (t0) >> 181 bne t0, t1, 1b >> 182 >> 183 LONG_S a0, fw_arg0 # firmware arguments >> 184 LONG_S a1, fw_arg1 >> 185 LONG_S a2, fw_arg2 >> 186 LONG_S a3, fw_arg3 >> 187 >> 188 MTC0 zero, CP0_CONTEXT # clear context register >> 189 PTR_LA $28, init_thread_union >> 190 /* Set the SP after an empty pt_regs. */ >> 191 PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE >> 192 PTR_ADDU sp, $28 >> 193 back_to_back_c0_hazard >> 194 set_saved_sp sp, t0, t1 >> 195 PTR_SUBU sp, 4 * SZREG # init stack pointer 360 196 361 ENDPROC(cpu_restart) !! 197 j start_kernel >> 198 END(kernel_entry) 362 199 363 #endif /* CONFIG_HOTPLUG_CPU */ !! 200 __CPUINIT 364 201 >> 202 #ifdef CONFIG_SMP 365 /* 203 /* 366 * DATA section !! 204 * SMP slave cpus entry point. Board specific code for bootstrap calls this >> 205 * function after setting up the stack and gp registers. 367 */ 206 */ >> 207 NESTED(smp_bootstrap, 16, sp) >> 208 #ifdef CONFIG_MIPS_MT_SMTC >> 209 /* >> 210 * Read-modify-writes of Status must be atomic, and this >> 211 * is one case where CLI is invoked without EXL being >> 212 * necessarily set. The CLI and setup_c0_status will >> 213 * in fact be redundant for all but the first TC of >> 214 * each VPE being booted. >> 215 */ >> 216 DMT 10 # dmt t2 /* t0, t1 are used by CLI and setup_c0_status() */ >> 217 jal mips_ihb >> 218 #endif /* CONFIG_MIPS_MT_SMTC */ >> 219 setup_c0_status_sec >> 220 smp_slave_setup >> 221 #ifdef CONFIG_MIPS_MT_SMTC >> 222 andi t2, t2, VPECONTROL_TE >> 223 beqz t2, 2f >> 224 EMT # emt >> 225 2: >> 226 #endif /* CONFIG_MIPS_MT_SMTC */ >> 227 j start_secondary >> 228 END(smp_bootstrap) >> 229 #endif /* CONFIG_SMP */ 368 230 369 __REFDATA !! 231 __FINIT 370 .align 4 << 371 ENTRY(start_info) << 372 .long init_thread_union + KERNEL_STA << 373 << 374 /* << 375 * BSS section << 376 */ << 377 << 378 __PAGE_ALIGNED_BSS << 379 #ifdef CONFIG_MMU << 380 ENTRY(swapper_pg_dir) << 381 .fill PAGE_SIZE, 1, 0 << 382 END(swapper_pg_dir) << 383 #endif << 384 ENTRY(empty_zero_page) << 385 .fill PAGE_SIZE, 1, 0 << 386 END(empty_zero_page) <<
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.