Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / arch / xtensa / kernel / head.S
diff --git a/kernel/arch/xtensa/kernel/head.S b/kernel/arch/xtensa/kernel/head.S
new file mode 100644 (file)
index 0000000..15a461e
--- /dev/null
@@ -0,0 +1,380 @@
+/*
+ * arch/xtensa/kernel/head.S
+ *
+ * Xtensa Processor startup code.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2008 Tensilica Inc.
+ *
+ * Chris Zankel <chris@zankel.net>
+ * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
+ * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
+ * Kevin Chea
+ */
+
+#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>
+
+/*
+ * This module contains the entry code for kernel images. It performs the
+ * minimal setup needed to call the generic C routines.
+ *
+ * Prerequisites:
+ *
+ * - The kernel image has been loaded to the actual address where it was
+ *   compiled to.
+ * - a2 contains either 0 or a pointer to a list of boot parameters.
+ *   (see setup.c for more details)
+ *
+ */
+
+/*
+ *  _start
+ *
+ *  The bootloader passes a pointer to a list of boot parameters in a2.
+ */
+
+       /* The first bytes of the kernel image must be an instruction, so we
+        * manually allocate and define the literal constant we need for a jx
+        * instruction.
+        */
+
+       __HEAD
+       .begin  no-absolute-literals
+
+ENTRY(_start)
+
+       /* Preserve the pointer to the boot parameter list in EXCSAVE_1 */
+       wsr     a2, excsave1
+       _j      _SetupOCD
+
+       .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
+       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
+
+#if XCHAL_HAVE_VECBASE
+       movi    a2, VECBASE_RESET_VADDR
+       wsr     a2, vecbase
+#endif
+
+       /* Clear debugging registers. */
+
+#if XCHAL_HAVE_DEBUG
+#if XCHAL_NUM_IBREAK > 0
+       wsr     a0, ibreakenable
+#endif
+       wsr     a0, icount
+       movi    a1, 15
+       wsr     a0, icountlevel
+
+       .set    _index, 0
+       .rept   XCHAL_NUM_DBREAK - 1
+       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
+
+       /* Disable zero-loops. */
+
+#if XCHAL_HAVE_LOOPS
+       wsr     a0, lcount
+#endif
+
+       /* Disable all timers. */
+
+       .set    _index, 0
+       .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
+
+       /* Disable coprocessors. */
+
+#if XCHAL_HAVE_CP
+       wsr     a0, cpenable
+#endif
+
+       /*  Initialize the caches.
+        *  a2, a3 are just working registers (clobbered).
+        */
+
+#if XCHAL_DCACHE_LINE_LOCKABLE
+       ___unlock_dcache_all a2 a3
+#endif
+
+#if XCHAL_ICACHE_LINE_LOCKABLE
+       ___unlock_icache_all a2 a3
+#endif
+
+       ___invalidate_dcache_all a2 a3
+       ___invalidate_icache_all a2 a3
+
+       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
+        * creates a table located at __boot_reloc_table_start
+        * that contans the information what data needs to be unpacked.
+        *
+        * Uses a2-a7.
+        */
+
+       movi    a2, __boot_reloc_table_start
+       movi    a3, __boot_reloc_table_end
+
+1:     beq     a2, a3, 3f      # no more entries?
+       l32i    a4, a2, 0       # start destination (in RAM)
+       l32i    a5, a2, 4       # end desination (in RAM)
+       l32i    a6, a2, 8       # start source (in ROM)
+       addi    a2, a2, 12      # next entry
+       beq     a4, a5, 1b      # skip, empty entry
+       beq     a4, a6, 1b      # skip, source and dest. are the same
+
+2:     l32i    a7, a6, 0       # load word
+       addi    a6, a6, 4
+       s32i    a7, a4, 0       # store word
+       addi    a4, a4, 4
+       bltu    a4, a5, 2b
+       j       1b
+
+3:
+       /* All code and initialized data segments have been copied.
+        * Now clear the BSS segment.
+        */
+
+       movi    a2, __bss_start # start of BSS
+       movi    a3, __bss_stop  # end of BSS
+
+       __loopt a2, a3, a4, 2
+       s32i    a0, a2, 0
+       __endla a2, a4, 4
+
+#if XCHAL_DCACHE_IS_WRITEBACK
+
+       /* After unpacking, flush the writeback cache to memory so the
+        * instructions/data are available.
+        */
+
+       ___flush_dcache_all a2 a3
+#endif
+       memw
+       isync
+       ___invalidate_icache_all a2 a3
+       isync
+
+       movi    a6, 0
+       xsr     a6, excsave1
+
+       /* init_arch kick-starts the linux kernel */
+
+       movi    a4, init_arch
+       callx4  a4
+
+       movi    a4, start_kernel
+       callx4  a4
+
+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
+ */
+       
+__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)