diff options
Diffstat (limited to 'arch/xtensa/kernel/head.S')
| -rw-r--r-- | arch/xtensa/kernel/head.S | 253 |
1 files changed, 192 insertions, 61 deletions
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index 3ef91a73652..aeeb3cc8a41 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S @@ -7,7 +7,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001 - 2005 Tensilica Inc. + * Copyright (C) 2001 - 2008 Tensilica Inc. * * Chris Zankel <chris@zankel.net> * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca> @@ -18,6 +18,8 @@ #include <asm/processor.h> #include <asm/page.h> #include <asm/cacheasm.h> +#include <asm/initialize_mmu.h> +#include <asm/mxregs.h> #include <linux/init.h> #include <linux/linkage.h> @@ -47,34 +49,65 @@ */ __HEAD - .globl _start -_start: _j 2f - .align 4 -1: .word _startup -2: l32r a0, 1b - jx a0 - - .section .init.text, "ax" - .align 4 -_startup: + .begin no-absolute-literals - /* Disable interrupts and exceptions. */ - - movi a0, LOCKLEVEL - wsr a0, PS +ENTRY(_start) /* Preserve the pointer to the boot parameter list in EXCSAVE_1 */ + wsr a2, excsave1 + _j _SetupOCD - wsr a2, EXCSAVE_1 - - /* Start with a fresh windowbase and windowstart. */ + .align 4 + .literal_position +.Lstartup: + .word _startup + .align 4 +_SetupOCD: + /* + * Initialize WB, WS, and clear PS.EXCM (to allow loop instructions). + * Set Interrupt Level just below XCHAL_DEBUGLEVEL to allow + * xt-gdb to single step via DEBUG exceptions received directly + * by ocd. + */ movi a1, 1 movi a0, 0 - wsr a1, WINDOWSTART - wsr a0, WINDOWBASE + wsr a1, windowstart + wsr a0, windowbase + rsync + + movi a1, LOCKLEVEL + wsr a1, ps rsync + .global _SetupMMU +_SetupMMU: + Offset = _SetupMMU - _start + +#ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX + initialize_mmu +#if defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY + rsr a2, excsave1 + movi a3, 0x08000000 + bgeu a2, a3, 1f + movi a3, 0xd0000000 + add a2, a2, a3 + wsr a2, excsave1 +1: +#endif +#endif + .end no-absolute-literals + + l32r a0, .Lstartup + jx a0 + +ENDPROC(_start) + + __REF + .literal_position + +ENTRY(_startup) + /* Set a0 to 0 for the remaining initialization. */ movi a0, 0 @@ -82,59 +115,50 @@ _startup: /* Clear debugging registers. */ #if XCHAL_HAVE_DEBUG - wsr a0, IBREAKENABLE - wsr a0, ICOUNT +#if XCHAL_NUM_IBREAK > 0 + wsr a0, ibreakenable +#endif + wsr a0, icount movi a1, 15 - wsr a0, ICOUNTLEVEL + wsr a0, icountlevel .set _index, 0 .rept XCHAL_NUM_DBREAK - 1 - wsr a0, DBREAKC + _index + wsr a0, SREG_DBREAKC + _index .set _index, _index + 1 .endr #endif /* Clear CCOUNT (not really necessary, but nice) */ - wsr a0, CCOUNT # not really necessary, but nice + wsr a0, ccount # not really necessary, but nice /* Disable zero-loops. */ #if XCHAL_HAVE_LOOPS - wsr a0, LCOUNT + wsr a0, lcount #endif /* Disable all timers. */ .set _index, 0 - .rept XCHAL_NUM_TIMERS - 1 - wsr a0, CCOMPARE + _index + .rept XCHAL_NUM_TIMERS + wsr a0, SREG_CCOMPARE + _index .set _index, _index + 1 .endr /* Interrupt initialization. */ movi a2, XCHAL_INTTYPE_MASK_SOFTWARE | XCHAL_INTTYPE_MASK_EXTERN_EDGE - wsr a0, INTENABLE - wsr a2, INTCLEAR + wsr a0, intenable + wsr a2, intclear /* Disable coprocessors. */ -#if XCHAL_CP_NUM > 0 - wsr a0, CPENABLE +#if XCHAL_HAVE_CP + wsr a0, cpenable #endif - /* Set PS.INTLEVEL=1, PS.WOE=0, kernel stack, PS.EXCM=0 - * - * Note: PS.EXCM must be cleared before using any loop - * instructions; otherwise, they are silently disabled, and - * at most one iteration of the loop is executed. - */ - - movi a1, 1 - wsr a1, PS - rsync - /* Initialize the caches. * a2, a3 are just working registers (clobbered). */ @@ -152,6 +176,37 @@ _startup: isync +#ifdef CONFIG_HAVE_SMP + movi a2, CCON # MX External Register to Configure Cache + movi a3, 1 + wer a3, a2 +#endif + + /* Setup stack and enable window exceptions (keep irqs disabled) */ + + movi a1, start_info + l32i a1, a1, 0 + + movi a2, (1 << PS_WOE_BIT) | LOCKLEVEL + # WOE=1, INTLEVEL=LOCKLEVEL, UM=0 + wsr a2, ps # (enable reg-windows; progmode stack) + rsync + + /* Set up EXCSAVE[DEBUGLEVEL] to point to the Debug Exception Handler.*/ + + movi a2, debug_exception + wsr a2, SREG_EXCSAVE + XCHAL_DEBUGLEVEL + +#ifdef CONFIG_SMP + /* + * Notice that we assume with SMP that cores have PRID + * supported by the cores. + */ + rsr a2, prid + bnez a2, .Lboot_secondary + +#endif /* CONFIG_SMP */ + /* Unpack data sections * * The linker script used to build the Linux kernel image @@ -199,25 +254,13 @@ _startup: ___flush_dcache_all a2 a3 #endif + memw + isync + ___invalidate_icache_all a2 a3 + isync - /* Setup stack and enable window exceptions (keep irqs disabled) */ - - movi a1, init_thread_union - addi a1, a1, KERNEL_STACK_SIZE - - movi a2, 0x00040001 # WOE=1, INTLEVEL=1, UM=0 - wsr a2, PS # (enable reg-windows; progmode stack) - rsync - - /* Set up EXCSAVE[DEBUGLEVEL] to point to the Debug Exception Handler.*/ - - movi a2, debug_exception - wsr a2, EXCSAVE + XCHAL_DEBUGLEVEL - - /* Set up EXCSAVE[1] to point to the exc_table. */ - - movi a6, exc_table - xsr a6, EXCSAVE_1 + movi a6, 0 + xsr a6, excsave1 /* init_arch kick-starts the linux kernel */ @@ -230,6 +273,92 @@ _startup: should_never_return: j should_never_return +#ifdef CONFIG_SMP +.Lboot_secondary: + + movi a2, cpu_start_ccount +1: + l32i a3, a2, 0 + beqi a3, 0, 1b + movi a3, 0 + s32i a3, a2, 0 + memw +1: + l32i a3, a2, 0 + beqi a3, 0, 1b + wsr a3, ccount + movi a3, 0 + s32i a3, a2, 0 + memw + + movi a6, 0 + wsr a6, excsave1 + + movi a4, secondary_start_kernel + callx4 a4 + j should_never_return + +#endif /* CONFIG_SMP */ + +ENDPROC(_startup) + +#ifdef CONFIG_HOTPLUG_CPU + +ENTRY(cpu_restart) + +#if XCHAL_DCACHE_IS_WRITEBACK + ___flush_invalidate_dcache_all a2 a3 +#else + ___invalidate_dcache_all a2 a3 +#endif + memw + movi a2, CCON # MX External Register to Configure Cache + movi a3, 0 + wer a3, a2 + extw + + rsr a0, prid + neg a2, a0 + movi a3, cpu_start_id + s32i a2, a3, 0 +#if XCHAL_DCACHE_IS_WRITEBACK + dhwbi a3, 0 +#endif +1: + l32i a2, a3, 0 + dhi a3, 0 + bne a2, a0, 1b + + /* + * Initialize WB, WS, and clear PS.EXCM (to allow loop instructions). + * Set Interrupt Level just below XCHAL_DEBUGLEVEL to allow + * xt-gdb to single step via DEBUG exceptions received directly + * by ocd. + */ + movi a1, 1 + movi a0, 0 + wsr a1, windowstart + wsr a0, windowbase + rsync + + movi a1, LOCKLEVEL + wsr a1, ps + rsync + + j _startup + +ENDPROC(cpu_restart) + +#endif /* CONFIG_HOTPLUG_CPU */ + +/* + * DATA section + */ + + .section ".data.init.refok" + .align 4 +ENTRY(start_info) + .long init_thread_union + KERNEL_STACK_SIZE /* * BSS section @@ -239,6 +368,8 @@ __PAGE_ALIGNED_BSS #ifdef CONFIG_MMU ENTRY(swapper_pg_dir) .fill PAGE_SIZE, 1, 0 +END(swapper_pg_dir) #endif ENTRY(empty_zero_page) .fill PAGE_SIZE, 1, 0 +END(empty_zero_page) |
